Notifications
Clear all

[Closed] Reorder an object array

I know the subject has already been covered, but I unable to find a solution for what I’m looking for.

I tried using code from this page but i’ve been unable to adapt it.


fn sortArrayByHeirarchy objectArray =( 
	sortedArray=#()
	childArray=#()
	-- first find roots and put them at left
	for obj in objectArray do(
	if (finditem objectArray obj.parent) == 0 then append sortedArray obj else append childArray obj 
	)
	-- now insert children on immediate right of their parents
	-- repeat scan until child array is empty
	while childArray.count > 0 do(
		i=1
		while i <= childArray.count do
		(
			parentIdx = finditem sortedArray childArray[i].parent
			if parentIdx != 0 then(
			insertItem childArray[i] sortedArray (parentIdx+1) 
			deleteItem childArray i
			) 
			else(
				i += 1 
			)
		)
	)
	sortedArray
)
sortedArr = sortArrayByHeirarchy (selection as array)
for obj in sortedArr do print obj.name

So the logic works, HOWEVER it doesn’t work if one of the object doesn’t have a direct link with another one in the array ( direct parenting)

So let’s say we’re using a biped and we select #(“Bip001 R Forearm”, “Bip001 R Hand”, “Bip001 R UpperArm”, “Bip001 Spine”, “Bip001 L Forearm”)
Running that function would return Bip001 R UpperArm as parent ( which is wrong )

I know this part

 (finditem objectArray obj.parent) == 0

is causing the issue but I have no idea whatsoever about how to fix/avoid this issue.

Any help please ?:sad:

23 Replies

This fn will create an array where is the first item parent and rest childrens

fn getFamilyTree objs = if objs.count != 0 do
 (
 	local parents = #()
 	fn getGrandpa obj = (while obj.parent != undefined do (obj = obj.parent)).name
 	for o in objs where isValidNode o.parent do appendIfUnique parents (getGrandpa o)
 	case parents.count of
 	(
 		0: "Objects are not linked!"
 		1: (join #() (getNodeByName parents[1]))
 		default: (for p in parents collect (join #() (getNodeByName p)))
 	)
 )
 getFamilyTree selection

Branko,
i can’t believe that you can’t do it better…

because everything is so easy.
#1 make a function that says if one node is a parent (or any grand->parent) of a specified one
#2 make a qsort function that uses is_parent function
#3 qsort list using sort_by_parent function

or


fn isParent node parent = (...)
fn sortByHieararchy n1 n2 = (if isParent n1 n2 then 1 else if isParent n2 n1 then -1 else 0)
fn makeHierarchyOrder nodes =
(
	qsort nodes sortByHieararchy 
	nodes
)

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

I can do better but I’m currently in a hurry to finish some arch-project for tomorrow.
I just wrote something that popped into my mind without much thinking.
Sorry to disappoint U. 🙁

BTW I’m just curious , what’s wrong with my fn?

6 Replies
(@denist)
Joined: 11 months ago

Posts: 0
<list> = collect <node>.name
finditem <list> node.name

this is very bad

(@gazybara)
Joined: 11 months ago

Posts: 0

What about this

fn isParent node parent = 
  ( 
  	if (state = node.parent == parent) or (parent.parent == node) then (if state then 1 else -1) else 0
  )
  fn sortByHieararchy n1 n2 = (isParent n1 n2)
(@denist)
Joined: 11 months ago

Posts: 0

no… it’s not about the real papa… it’s about a grandpa as well
the function isParent has to answer the question: is there your blood in my veins?
so it has to ask WHILE

(@gazybara)
Joined: 11 months ago

Posts: 0

This?

fn isParent node parent = ((while node.parent != undefined do (node = node.parent)) == parent)
(@denist)
Joined: 11 months ago

Posts: 0

this is hot… but how is about node.parent == parent and you have to fix the return value

(@gazybara)
Joined: 11 months ago

Posts: 0

You mean not equal ei:
fn isParent node parent = ((while node.parent != undefined do (node = node.parent)) != parent)

never do it this way. usually it doesn’t work.

and… for anyone who thinks he is a rigger (a technical animator) this is_parent function will be a gift:

fn isKindaAChild me you = not isKindaAParent me you
 fn getMeMyParents you nodes: = ....
 fn makeAChain fromNode toNode = ...
 

:
why are they interesting for a rigger? interpretation:
#1 does my transform dependency looped to these nodes (… there is another way to know that)
#2 after my parent dies who would be my most relative?
#3 he-he… IK to FK… who needs to be baked?

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

You continue to confuse people with your advanced-custom fn’s. U trick me onece when I try to find these in mxs help

while loop the same as for loop finally returns OK… we need a boolean

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

Yup but this while loop always returns anode. Take a look this example where I test it by using linked nodes and when node not have any parent (point helper)

fn isParent node parent = ((while node.parent != undefined do (node = node.parent)) == parent)
 in (in (in (d = dummy()) dummy pos:[15,0,0]) dummy pos:[30,0,0]) dummy pos:[45,0,0]
 dArr = $Dummy* as array
 p = Point pos:[-30,0,0]
 
 isParent dArr[4] dArr[1]
 --> true
 isParent dArr[4] p
 --> false

This is what Denis showed to us(me and Branko) a while ago:

fn GetRootParent obj = if obj.parent != undefined do
	(
		while obj != undefined and (obj.parent != undefined) do
			(obj = obj.parent)
		obj
	)

My try:


fn IsParent theArray =
(
	for obj in theArray do 
	(
		while (getNodeByName obj).parent != undefined do 
		(
			obj = (getNodeByName obj).parent.name
			if (finditem theArray (getNodeByName obj).name) != 0 then return true
		)
	)
	return false
)
IsParent (for o in selection collect o.name)

I dont lilke having to collect name and use getNodeByName but it works

I guess there’s something wrong cause when I combine my Isparent fn with sorth hierarchy and qsort I dont get the correct results

1 node gets misplaced in the array

alright had to rewrite my Isparent to make is much more simpler and doesnt require name now which annoyed me anyway

works like a charm :applause: :bounce:

gotta admit that this qsort thing was new to me and after some reading in the help file ,this post and this article I feel like a new world a just opened 😮

Page 1 / 2