[Closed] Move ojbects in a group to a specified layer
You da’ Man!
I made a slight modification based on one of the other code strings (so that a new layer was created to avoid problems with putting everything in another ‘set of groups’ in the same layer if this script has to be run more than once in a scene)
ActiveSelection = #()
GroupedObj = #()
for s = 1 to ActiveSelection.count do (if isGroupMember Selection[s] then (append GroupedObj ActiveSelection[s]) else false)
for GroupedObj in Selection where isGroupMember GroupedObj AND (NOT isOpenGroupMember GroupedObj) do setGroupOpen GroupedObj.parent true
layer = LayerManager.NewLayer(); for node in selection do (layer.addNode node)
For some reason, the line breaks were causing problems as well, so removing the line break and just adding a ; seemed to make Max read it just fine.
Ahhh, progress…What I typically do is copy the code over to something like textpad and back again into max. Max’s script editor is actually capable of some formatting, which can really screw you around…but that’s just me
Okay… I’m not sure if this will be biting off more than I can chew, but how would I go about replacing the bit where it says “LayerManager.NewLayer();” with something that would allow me to either select an existing layer from a list?
Ideally, I’d like to be able to have a list to select from with the option of creating a new layer as well, but if this is going to be a nightmare to figure out code for I may just stick with what I’ve got.
It looks like “listbox” may be my answer, but I can only find info on how to make the list box select an array of items from the scene. How do I get it to list the layers in the Layer Manager?
Edit:
Okay, now I have this;
ActiveSelection = #()
GroupedObj = #()
for s = 1 to ActiveSelection.count do (if isGroupMember Selection[s] then (append GroupedObj ActiveSelection[s]) else false)
for GroupedObj in Selection where isGroupMember GroupedObj AND (NOT isOpenGroupMember GroupedObj) do setGroupOpen GroupedObj.parent true
PickLayer = (rollout DestLayer "Destination Layer"
(
dropdownlist Layers "Select Layer"
on dropdownlist selected do LayerManager.getLayerName
)
createDialog DestLayer
)
LayerOne = layermanager.getlayerfromname "PickLayer"
for node in selection do (layer.addNode node)
It creates an empty dropdown list at the moment. What am I doing wrong that is keeping it from populating the list with the layer names?
(by the way, thanks for the tip about Max’s script editor… that was the source of several issues)
Think of it this way…the list is an idiot. Unless you tell exactly what you want, it has no idea of what you want…just like me, it can’t read your mind…oh, if only it could, how easy would that be
What you need to do is initalise it with a list of values
Now I believe you could do something like this…
-- Create a new empty array
layerList = #()
-- Make sure there is at least 1 layer avaliable, otherwise we might
-- cause an error
if (LayerManager.count > 0) then (
-- Loop through the layer list
-- This must be one of the few collections to be zero indexed?!
for i = 0 to LayerManager.count - 1 do (
-- Add each new layer to the array...we only want the NAMES!!
-- This is important, because this is what will be displayed to the
-- user in the dropdown list...
append layerList (LayerManager.getLayer i).name
)
)
-- Place holder for the selected layer
selectedLayer = undefined
rollout DestLayer "Destination Layer" (
dropdownlist Layers "Select Layer" [b]items:layerList
[/b] on dropdownlist selected [b]index [/b]do (
[b] local layerName = layerList[index]
selectedLayer = (getLayerFromName layerName)
[/b]
-- Close the dialog automatically when the user selects a new layer...
-- This may not be the best solution, but it will do for the momement
-- and demonstrates how to dismiss a dialog
[b]DestroyDialog DestLayer
[/b] )
)
-- Create a MODEL dialog. This will stop the script execution here
-- until the dialog is dismissed or closed by the user...
createDialog DestLayer width:100 heigh:100 [b]model:true
[/b]if (selectedLayer != undefined) then (
-- Continue with the script, moving the objects to the new layer...
) else (
-- User did not select a layer!??
-- In this example, the only way this can occur is if the user manually closes the dialog
-- by hitting the nice big red "x"
)
Okay, I’ve not tested any of this, but try JUST this code and see where it gets you BEFORE incorprating it into the rest of the script…
alright, the code you put up does display a list of the active layers, but does not seem to dismiss the dialog for some reason (I looked up the destroyDialog topic in the help file and it looks like what you have there should have worked… so I’m scratching my head a bit there).
I tried adding in my code a piece at a time, and it seems like when I get the dialog, I make a selection, the dialog stays up and nothing else changes. I’m supposing that if the dialog can be sucessfully dismissed, it will complete the process and populate the layer selection with the selected objects (I hope).
Presumably, once I have that working could I add an ‘else’ clause that would give the option of adding a new layer? That may be too much, so if it is I’ll be happy with what I’ve got.
Sorry, my bad…the event handler should actually read
on [b]Layers [/b]selected index do (
local layerName = layerList[index]
selectedLayer = ([b]LayerManager.[/b]getLayerFromName layerName)
-- Close the dialog automatically when the user selects a new layer...
-- This may not be the best solution, but it will do for the momement
-- and demonstrates how to dismiss a dialog
DestroyDialog DestLayer
)
That’ll teach me not to test my code…
And yes, if the user does not select a layer and dismisses the dialog, you could create another one asking for the new layer…or you could supply a textfield to collect the new name and use a button to dismiss the dialog…
I tend to like getting as few dialogs as possible…but that’s cause I’m lazy…
Shane
I think I’ll curl up into a ball then sit in the corner and cry for a few hours when this is all said and done… and have MaxScript nightmares for the next few years.
It seems like every time I get a piece of code to work, there’s another bit that is blowing up on me, and I’m so new to this stuff that I’m sure I’m just missing some really basic steps along the way.
Edited –
Here’s what I’ve got…
ActiveSelection = #()
GroupedObj = #()
for s = 1 to ActiveSelection.count do (if isGroupMember Selection[s] then (append GroupedObj ActiveSelection[s]) else false)
for GroupedObj in Selection where isGroupMember GroupedObj AND (NOT isOpenGroupMember GroupedObj) do setGroupOpen GroupedObj.parent true
layerList = #()
if (LayerManager.count > 0) then (for i = 0 to LayerManager.count - 1 do (append layerList (LayerManager.getLayer i).name
)
)
selectedLayer = undefined
(
rollout DestinationLayer "Layers"
(
dropdownlist Layers "Select Layer" items:layerList
on Layers selected index do
(
local layerName = layerList[index]
selectedLayer = (LayerManager.getLayerFromName layerName)
)
)
)
createDialog DestinationLayer width:100 heigh:100 model:true;
--if (selectedLayer != undefined) then (for node in selection do (selectedLayer.addNode node))
--DestroyDialog DestinationLayer
--actionMan.executeAction 0 "40143"
This shows everything open and has a list of layers to select from. That means that whay I’ve messed up is the last part of the code here, right? What do I need in order to accept the selection from the user, close the dialog, and close the group?
Okay…a couple of quick things…
(
rollout DestinationLayer "Layers"
(
dropdownlist Layers "Select Layer" items:layerList
on Layers selected index do
(
local layerName = layerList[index]
selectedLayer = (LayerManager.getLayerFromName layerName)
)
)
)
)
This isn’t going to work the way you appear to think it will…
The rollout clause is a “defination”, not a “script” per say (for the moment, you don’t need to understand)…You’ve also enclosed it within in it’s own context, which hides it from the rest of the script…not what you want…
createDialog DestinationLayer width:100 heigh:100 model:true;
This is wrong, sorry, my bad, it’s modal not model…
I still don’t understand why you feel the need to open the groups…I can do it without the need to.
If, however, you feel that you have to, collect the group head’s into an array and close them at the end of the script, don’t use the action manager, it is contextual…
This is the script I’ve been able to come up with. It works quite well on the sample scene you provided…try it as it stands…
-- Used to specify the layer of choice...
selectedLayer = undefined
-- Define the rollout for later use...it's a special kind of function...but not a function...
rollout DestLayer "Layers"
(
dropdownlist Layers "Select Layer" items:layerList
on Layers selected index do (
local layerName = layerList[index]
selectedLayer = (LayerManager.getLayerFromName layerName)
DestroyDialog DestLayer
)
)
-- Get a list of all the layers
layerList = #()
if (LayerManager.count > 0) then (
for i = 0 to LayerManager.count - 1 do (
append layerList (LayerManager.getLayer i).name
)
)
-- Create our modal dialog
createDialog DestLayer width:100 heigh:100 modal:true
-- If the user selected a layer, then move the objects
if (selectedLayer != undefined) then
--Then comes the part of the script I expected to have move my objects to the chosen layer
(for node in selection do (selectedLayer.addNode node)
) else (
--not sure what to put here
-- Print nasty messages about the user...;)
-- The user has failed to select a layer...do what ever you think you need to do...
)
Shane
Excellent, it works! I had to swap two chunks of the code around (it gave a compile error if I didn’t define what the ‘layerlist’ was before doing the rollout), but it works great otherwise.
It may work differently if it’s processed in MaxScript rather than straight through Max itself (and not consistantly either), but we frequently find that when you try to assign a grouped selection with nested groups to a new layer, only portions of the selection will transfer to the new layer… some items stay put for some reason (hence the need to first open the groups). If the way things are processed when running that command as a script works differently, I’m all for it. I’ve got some more files to test it on first.
Yep, should have seen that – must have still had layerlist defined in my global context when I was finalising the script…I ususally work with a local context for this reason, but seen as you figured it out, that’s all the matters
It may work differently if it’s processed in MaxScript rather than straight through Max itself (and not consistantly either), but we frequently find that when you try to assign a grouped selection with nested groups to a new layer, only portions of the selection will transfer to the new layer… some items stay put for some reason (hence the need to first open the groups). If the way things are processed when running that command as a script works differently, I’m all for it. I’ve got some more files to test it on first.
I think I might have to do with the way max treats it’s layers. In maxscript, you can access ALL the objects in the group without doing anything special, but the UI tends to treat or differently…so long as it works…
Shane