[Closed] Select And Sort objects in the scene
Hi i have a little issue in loading data:
in the scene i have a list of editable_mesh or editable_poly with this name sequence:
"mesh-0001-cpx01-str01-obj11-1"
"mesh-0002-..."
"mesh-0004-..."
"mesh-0003-..."
ecc…
and now i want an array of obj with “mesh–…” sorted ascending.
the code:
$geometry/mesh*
create an array of objects but not in sorted name:
#(mesh-0001,mesh0002,mesh0004,mesh0003) because it select with a sort of timeline creation, not name ordered…
can i do to create am array of objects ?
exemple:
for 435 objects:
clearListener()
FN FindMesh List num=
(
found = false
listCount = list.count
n = 1
while not found and n<= listCount do
(
found = false
obj = list[n]
nome = filterstring obj.name "-"
nome = nome[2] as integer
if nome==num do found = true
n+=1
)
if n>=listCount and not found then 0 else n-1
)
function LoadMesh =
(
st = timestamp()
PathCollector = $geometry/mesh*
data = for obj in PathCollector collect obj
sortData = #()
sortData[data.count] = undefined
print data.count
m = 1
for i=1 to data.count do
(
idx = FindMesh data m
sortData[i]=data[idx]
--print data[idx].name
m+=1
)
print ("calculated in ms: " + (timestamp()-st) as string)
--for obj in sortData do print obj.name
return sortData
)
data = LoadMesh()
calculated in 2023 ms, but is very slow !!!
ops, i found a simple solution…
function LoadMesh =
(
st = timestamp()
dataIdx=#()
PathCollector = $geometry/mesh*
data = for obj in PathCollector collect obj
sortData = #()
sortData[data.count] = undefined
for obj in data do
(
nome = filterstring obj.name "-"
append dataIdx (nome[2] as integer)
)
for i=1 to data.count do
(
n = findItem dataIdx i
sortData[i] = data[n]
)
print ("calculated in ms: " + (timestamp()-st) as string)
sortData
)
data = LoadMesh()
Now the time in ms is 10 !!!
first of all I would use more detailed wild card for the pathname:
$geometry/'mesh-????-*'
Using qsort (see MXS help for qsort) to make custom sort function:
One of the possible solutions:
fn sortMeshXXXX n1 n2 = stricmp (substring n1.name 1 10) (substring n2.name 1 10)
Now it’s all together:
fn getMyMeshes =
(
fn sortMeshXXXX n1 n2 = stricmp (substring n1.name 1 10) (substring n2.name 1 10)
nodes = $geometry/'mesh-????-*' as array
qsort nodes sortMeshXXXX
nodes
)
it’s the better one. Faster and more memory friendly.
fn getMyMeshes =
(
struct meshXXXX (node, xxxx)
fn sortMeshXXXX n1 n2 =
(
if n1.xxxx < n2.xxxx then -1 else if n1.xxxx > n2.xxxx then 1 else (stricmp n1.node.name n2.node.name)
)
nodes = $geometry/'mesh-????-*' as array
if nodes.count > 1 then
(
nodes = for n in nodes collect (meshXXXX node:n xxxx:(substring n.name 6 4) )
qsort nodes sortMeshXXXX
for n in nodes collect n.node
)
else nodes
)
WOW, you are an expert in maxscript, thanks for solution, is very interesting !
With “qsort” is very simple sort the data, this is another example:
clearListener()
(
-- sintax of objects = "GameMain-" <number> "-data-"
fn getMeshes =
(
struct flipMesh (node, n ,m)
fn sortMesh obj1 obj2 =
(
case of
(
(obj1.n > obj2.n) : -1
(obj1.n < obj2.n) : 1
default : case of
(
(obj1.m > obj2.m) : -1
(obj1.m < obj2.m) : 1
default : 0
)
)
)
nodesList = GameMain-'* as array
if nodesList .count > 1 then
(
flipNodes = for obj in nodesList collect
(
flipName = filterString obj.name "-"
flipMesh node:obj n:(flipName[2] as integer) m:(flipName[4] as integer)
)
qsort flipNodes sortMesh
for obj in flipNodes collect obj.node
)
else nodesList
)
for i=1 to 1000 do
(
subNum = random 1 4
for j=1 to subNum do
(
stringa = stringStream ""
format "GameMain-%-data-%" i j to:stringa
obj = box name:stringa
)
)
st = timestamp()
data = getMeshes()
format "calculated % objects in % ms" data.count (timestamp()-st)
for obj in data do print obj.name
)