Notifications
Clear all

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

4 Replies

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
 )