[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
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.
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.