select layers

Hello maxscripters,
Do you know a way to select layers by script?
By advance, thanks!

Comments

Comment viewing options

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

.

What is the goal? Select layers and then?

Gnn's picture

Hello Miauu, there's a loong

Hello Miauu, there's a loong time that i haven't read you!
I was thinking if it was possible to use your script by differents methods and choices, as i'd like to run it an several scenes, for example:
- update assets by selecteds layers
- or update alls assets by layers founded under the layer Clones,
- or by a list separate by comma
- delete olds assets
then run your script as external and transfer arguments
fileIn ("E:\\Script\\UpdateSelectedsAssets.ms")
::selLayersArray
then select the layers to run the script you made?
but it seems to be impossible to select layers in maxscript??

miauu's picture

.

I assume that you do not want the user to select the layers manually.
The script should read the names of the layers from somewhere else(a txt file, using name patterns, etc.) and then to selects the proper layers. If what I assume is right, then you can pass the layers directly to the script that will manipulate them.

For example you have:
A text file that contains the names of the layers that have to be selected - LayersToSelect.txt.
Script with name "Select Layers" - to select arbitrary layers.
Script with name "See which layers are selected" - to get the selected layers.
Script with name "Manipulate Layers" - to works with selected layers.
In this situation your tool will works this way:
1- "Select Layers" reads the LayersToSelect.txt and selects the proper layers.
2- "See which layers are selected" collects the selected in the Layer Manager layers.
3- "Manipulate Layers" works with the selected layers.

But, your tool can works this way too:
1- "Manipulate Layers" reads the LayersToSelect.txt and works directly with the layers without selecting them.

This code will print in the MaxScript Listener the names of the selected layers.

(
	layerMngr = SceneExplorerManager.GetActiveExplorer()
	layersArr = layerMngr.SelectedItems()
 
	if layersArr.count != 0 do
	(
		for layer in layersArr do
		(
			format ": % \n" layer.name
		)
	)
)

This will select all layers which names starts with "Lay">

(
	function SelectLayers str = 
	(
		clearSelection()
		for i = 1 to LayerManager.count-1 where matchPattern (LayerManager.getLayer i).name pattern:(str +"*") do
		(
			(LayerManager.getLayer i).select on
		)
	)
	SelectLayers "Lay"
)

Both codes works in 3dsmax 2017. I did not test them in lower version.

Gnn's picture

thanks miauu, may be it's

thanks miauu,
may be it's because i'm working in version 2016, but it select some childs of layers, but not the layer itself,
so i'm going to test the other solution directly:
1- "Manipulate Layers" reads the LayersToSelect.txt and works directly with the layers without selecting them.
but the line (25) where i want to compare the layers to found (array) and layers inside the layers Characters (in the scene) doesn't work,
also the part where i'm trying to delete olds assets is working if layers are selected:

DeleteOldsAssets = "Yes"
LayerToFoundArr = #("Danael", "Jadina", "Shimy")
--or make a collection of alls layers childs founded under layer  "Characters"	
 
	mainLayerName = "Characters"	
	mainLayer = LayerManager.getLayerFromName mainLayerName		
 
	function GetObjectsInLayer layer: =
	(
		local objsArr
		layer.nodes &objsArr
		objsArr
	)	
	numChildLayers = mainLayer.getNumChildren()		
	if numChildLayers != 0 then
	(	
		for i = 1 to numChildLayers do
		(
			ChildLayersTmp = mainLayer.getChild i	
			ChildLayersName = ChildLayersTmp.name
			for o = 1 to LayerToFoundArr.count do	
			(				
				selLayersArr = for o in ChildLayersName where (matchpattern o.name pattern:("*" + LayerToFoundArr + "*")) collect o
				if selLayersArr.count != 0 do
				(
					--fileIn "G:\\Script\\UpdateSelectedsAssets.ms" 
					--::selLayersArr
 
					if DeleteOldsAssets == "Yes" then
					(	
/*
						layerExplorer = SceneExplorerManager.GetActiveExplorer()
						if layerExplorer != undefined do
						(
							local objs = #(), layers = #()
 
							mapped fn collectObjs item =
								if isKindOf item Base_Layer then
								(
									append layers item
									join objs (refs.dependentNodes item)
									items = (for c = 1 to item.getNumChildren() collect (item.getChild c).layerAsRefTarg)
									collectObjs items
								)
								else append objs item							
							collectObjs (layerExplorer.SelectedItems())
							delete objs
							for layer in layers where layer.canDelete() do LayerManager.deleteLayerByName layer.name
						)
*/
					)
				)
			)
		)
	)			
	objsInnLayerArr = GetObjectsInLayer layer:mainLayer
<code>
miauu's picture

.

Try this. I am not sure if the script will delete the proper layer, so modify it it it not works properly in that part.
No need the layers to be selected and the Layer Explorer to be open.
Tested in 3dsMax 2016. :)

(
	DeleteOldsAssets = "Yes"
	LayerToFoundArr = #("Danael", "Jadina", "Shimy")
--or make a collection of alls layers childs founded under layer  "Characters"	
 
	mainLayerName = "Characters"	
	mainLayer = LayerManager.getLayerFromName mainLayerName	
 
	objsArr = #()
	layersArr = #()	
 
	function GetObjectsInLayer layer: =
	(
		local objsArr
		layer.nodes &objsArr
		objsArr
	)	
 
	mapped fn collectObjs item =
	(
		if classof item == MixinInterface then
		(
			append layersArr item
			join objsArr (GetObjectsInLayer layer:item)
			items = (for c = 1 to item.getNumChildren() collect (item.getChild c).layerAsRefTarg)
			collectObjs items
		)
		else 
		(
			append objsArr item
		)
	)
 
 
	numChildLayers = mainLayer.getNumChildren()		
	if numChildLayers != 0 then
	(	
		for i = numChildLayers to 1 by -1 do
		(
			ChildLayersTmp = mainLayer.getChild i	
			ChildLayersName = ChildLayersTmp.name
 
			if (idx = (findItem LayerToFoundArr ChildLayersName)) != 0 do
			(
				if DeleteOldsAssets == "Yes" then
				(	
					objsArr = #()
					layersArr = #()						
					--	"collect the objects in the layer"
					CollectObjs ChildLayersTmp
					delete objsArr
					for layer in layersArr where layer.canDelete() do 
					(
						LayerManager.deleteLayerByName layer.name
					)
				)
			)
		)
	)			
	objsInnLayerArr = GetObjectsInLayer layer:mainLayer
)
Gnn's picture

Hello Miauu, i've done that

Hello Miauu, i've done that to make it work, if someone need it someday:

mainLayerName = "LayerName"	
childNames = #("Asset1", "Asset2", "Asset3")
 
mainLayer = LayerManager.getLayerFromName mainLayerName
layersArr = #()
objsArr = #()
 
fn getObjectsInLayer layer =
(
	layer.nodes &objs
	objs
)
 
mapped fn collectObjs item =
	if isKindOf item Base_Layer then
	(
		append layersArr item
		join objsArr (getObjectsInLayer item)
		local items = for c = 1 to item.getNumChildren() collect (item.getChild c).layerAsRefTarg
		collectObjs items
	)
	else append objsArr item
 
for i = 1 to mainLayer.getNumChildren() do
(
	local childLayer = (mainLayer.getChild i).layerAsRefTarg
	if findItem childNames childLayer.name > 0 do collectObjs childLayer
)
 
delete objsArr
for layer in layersArr where layer.canDelete() do LayerManager.deleteLayerByName layer.name
<code>
 
Thanks again for your help, have a good week :)
miauu's picture

.

I'm glad to help. :)

Comment viewing options

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