Notifications
Clear all

[Closed] Select objects by variable name

Hello CGTalk Community,

at the moment i am trying to select objects by a variable name. But everything i tried so far did not work. I am quite new to max script so maybe the answer isn’t that complicated.

Here’s what i’m trying to do. Wrong version of course


 q = 3
 for i = 1 to q do
 (
 waveName = ("cube_wave_" + q as string + )
 select ("$" + waveName + "*") -- here i want to select every object that starts with cube_wave_1 for example
 
 [...]
 )
 

thank you

7 Replies

Open the MAXScript Help. Look fro Frequently Asked Questions.
There is one entitled “How do I get the object by object name?” which should give you the basic idea.

Of course, in your case you will have to use “i as string” and not “q as string” since “i” is the variable that changes from 1 to q. So all you need is the execute call:

q = 3
 for i = 1 to q do
 (
 waveName = ("cube_wave_" + i as string )
 execute ("select $" + waveName + "*")
 )

… or


q = 3
for i = 1 to q do
(
  waveName = "cube_wave_" + i as string
  select (execute ("$" + waveName + "*"))
)

… or

local objs = objects as array
local objNames = for obj in objs collect obj.name
local objCount = objs.count

q = 3
for i = 1 to q do
(
	waveName = "cube_wave_" + i as string + "*"
	
	foundObjs = for i = 1 to objCount where matchPattern objNames[i] pattern:waveName collect objs[i]
	if foundObjs.count > 0 then select foundObjs else clearSelection()
	...
)

… or

local objs = objects as array
local objNames = for obj in objs collect obj.name
local objCount = objs.count

q = 3
for i = 1 to q do
(
	waveName = "cube_wave_" + i as string
	waveNameLen = waveName.count
	
	foundObjs = for i = 1 to objCount where substring objNames[i] 1 waveNameLen == waveName collect objs[i]
	if foundObjs.count > 0 then select foundObjs else clearSelection()
	...
)

… or

local objNamesStream = "" as stringStream
for i = 1 to objCount do format "%-%
" i objs[i].name to:objNamesStream
local objNames = objNamesStream as string
close objNamesStream

q = 3
for i = 1 to q do
(
	waveName = @"(\d+)\-(cube_wave_" + i as string + ".*)"
	regex = dotNetObject "System.Text.RegularExpressions.Regex" waveName
	matches = regex.matches objNames
	foundObjs = for i = 1 to matches.count collect objs[matches.item[i-1].groups.item[1].value as integer]
	if foundObjs.count > 0 then select foundObjs else clearSelection()
	...
)

etc …

On a related note: select will not keep the old selection if the given array/objectset/pathname contains no objects, so in that case you might want to call either clearSelection() or max select none.

Martijn

pathname searching is much-much faster then collecting by pattern (matchpattern or findstring):


(
	delete objects 
	for k=1 to 1000 do box name:("box" + k as string + "_any") 
	
	gc()

	t1 = timeStamp()
	m1 = heapfree
	for i=1 to 1000 do 
	(
		name =  "$box" + i as string + "*"
	    objs = execute name
		-- ...	
	)
	t2 = timeStamp()
	m2 = heapfree
	format "PATHNAME
	time:%
		memory:%
" (t2 - t1) (m1 - m2)

	gc()

	t1 = timeStamp()
	m1 = heapfree
	names = for obj in objects collect obj.name
	for i=1 to 1000 do 
	(
		name =  "box" + i as string + "*"
		objs = for n=1 to names.count where matchpattern names[n] pattern:name collect objects[n]
		-- ...
	)
	t2 = timeStamp()
	m2 = heapfree
	format "PATTERN SEARCH
	time:%
		memory:%
" (t2 - t1) (m1 - m2)
)

Of course it’s faster, but you can’t deny that using regex searches makes the code look a lot more sophisticated.

1 Reply
(@solitude)
Joined: 11 months ago

Posts: 0

Yeah, by far. I try to include as much sophisticated LOOKING stuff as possible… makes it that much more impressive when people look at your script. A side bonus of if it going slower, is that it can make it look like the whatever you coded is making the computer work really hard too (dually impressive to normal folk).

Thanks to all of you. I works perfectly now. I tried the “execute – version” first but since everyone recommends to avoid it i’ll check the other solutions too.