Script to make group of objects childs of another objects


#1

Hey guys,

I’ve got 2 question here, hope to receive some advice.

Is there a script to make an object a child of another object?
Here the thing: I’ve got 2 nulls, each stores 630 objects. And what I need is to make each object from null_0 a child of a corresponding object in null_1, based of their index relative to the corresponding nulls.

Since I’m going to operate with indexes I also need to rearrange objects in null_1. Is there a script to do so? The issue is that in null_0 objects are like [obj_0, obj_1, obj_2 … obj_629] while in the null_1 they are [obj_629, obj_628, obj_627 … obj_0].

I will be greatful for any help. Otherwise I’d need to do that manually 630 times :smiley:


#2

if i understood the assignment correctly, this script should do it:

import c4d

def main():

    parents_selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE)

    if len(parents_selection) < 2:
        return

    children_of_parent_A = parents_selection[0].GetChildren()
    children_of_parent_B = list(reversed(parents_selection[1].GetChildren()))

    doc.StartUndo()

    for i, child in enumerate(children_of_parent_A):
        old_mg = children_of_parent_B[i].GetMg()
        children_of_parent_B[i].InsertUnder(child)
        children_of_parent_B[i].SetMg(old_mg)
        c4d.EventAdd()

    doc.EndUndo()


if __name__=='__main__':
    main()

#3

almost forgot:
you need to select the two parent objects (your null_0 and null_1).
the children of the parent that is further down in your obj.manager are being placed under the respective children of the parent object that is further up, in reversed order, that is.
it is not being checked, that the number of children under each parent is the same.


#4

Omg, this works perfectly! Thanks a lot!

I hope I am not asking too much, but is it possible to add a line after parenting which would connect+delete parent+child?

I know a bit of python (currently studying JS since it is more needed in another soft I’m working with), but I suppose at this point it will be quite hard for me to figure out API method and proper implementation in python.


#5

i am not sure, i understand.

in a simple scenario, i have two parents, which each have, say, 10 children.
the script now takes the last child of the second parent and places it under the first child of the first parent.
then, the second to last is being placed under the second and so on…
at the end of the loop, the second parent has no children anymore.
the first parent has 10 children; themselves now are “parents”, due to each of those now having a child.

do you want each of the 10 “child-parents” to be connect+deleted with their respective child, so that, in the end, there is 1 parent left, which has 10 children (that are the result of the connect+delete action)?


#6

Ah, sorry if I did’t explain properly.

Here is what I mean:

With this script we have the following outcome:

Null_0:

  • obj_0 (from Null_0)
    • obj_0 (from Null_1
  • obj_1 (from Null_0)
    • obj_1 (from Null_1)
  • etc

What I am looking additionally is to add a line in “for i, child in enumerate …” loop that would “Connect objects + Delete” parent obj_n (from Null_0) and his child obj_n (from Null_1). So the outcome would be like:

Null_0:

  • obj_0 (connect+deleted obj_0 from Null_0 and obj_0 from Null_1)
  • obj_1 (connect+deleted obj_1 from Null_0 and obj_1 from Null_1)
    -etc

#7

i see. that should do the trick:

import c4d

def main():

    parents_selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE)

    if len(parents_selection) < 2:
        return

    children_of_parent_A = parents_selection[0].GetChildren()
    children_of_parent_B = list(reversed(parents_selection[1].GetChildren()))

    doc.StartUndo()

    for i, child in enumerate(children_of_parent_A):
        old_mg = children_of_parent_B[i].GetMg()
        children_of_parent_B[i].InsertUnder(child)
        children_of_parent_B[i].SetMg(old_mg)

    doc.SetActiveObject(parents_selection[0], mode=c4d.SELECTION_NEW)
    parent_new = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE)[0]

    for j, child in enumerate(parent_new.GetChildren()):

        doc.SetActiveObject(child, mode=c4d.SELECTION_NEW)
        doc.SetActiveObject(child.GetChildren()[0], mode=c4d.SELECTION_ADD)
        c4d.CallCommand(16768)

    c4d.EventAdd()
    doc.EndUndo()


if __name__=='__main__':
    main()

#8

This is amazing! Once again thank you for your help and time, really appreciate it!


#9

you are welcome.