[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:
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
)
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. 🙁
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)
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
This?
fn isParent node parent = ((while node.parent != undefined do (node = node.parent)) == parent)
this is hot… but how is about node.parent == parent and you have to fix the return value
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?
You continue to confuse people with your advanced-custom fn’s. U trick me onece when I try to find these in mxs help
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 😮