Page 1 of 1

How to batch add parent constraints?

Unread postPosted: Fri Apr 09, 2021 10:28 am
by weindy
Hi!

For some reason I need to rebuild a forest from maya layout scene. I did small forest before, made tree locator to abc file, then put in clarisse, manually added parent constraints for every tree to the locator, and all the tree position was perfect same! :D

Now this scene is too huge, even one kind of tree need add constraint over 200 times.. :shock:

So is there a script can batch add parent constraints? Just match name will be enough. One kind of tree locator can be named tree01_locator0x, maybe can put into a variable, then loop duplicate tree01 and add parent constraint?

Thank you very much!

Re: How to batch add parent constraints?

Unread postPosted: Mon Apr 12, 2021 8:26 pm
by bvz
here is a script that I use to attach items to locators.

It does not do parent constrains, but rather directly parents the items. It would be easy to modify to do parent constraints.


There is no UI, so here is how you use it:

You have to modify the script to have a list of the items you want to instance (the trees in your case). This tool will allow you to add more than one item and it will cycle through the items when doing the constraints. For example if you have the following three trees that you want to parent to the locators:

tree1
tree2
tree3

the tool will parent tree1 to locator1, tree2 to locator2, tree3 to locator3, then tree1 will be parented to locator4, tree2 to locator5, tree3 to locator6, etc...

If you do not want this behavior, only choose a single source tree at a time.


To use the script, do the following:

Select the items you want to instance one at a time and copy their full URL to the script (you see the list at the top of the script that currently holds a full url to a polygrid and a polyshere). This is the list of items that will be instanced.

Then, select all of the locators you want to parent to
Then ctrl-select the context where you want the instances to live

Then run the script. You will have instances of the objects in the list in the context you selected, and each of those instances will be parented to the items you selected when running the script.

Let me know if you need any more assistance with this.



Code: Select all
import re
import random


##########################################
#
# The user should select items in the following order:
#
# 1) Select all of the locators
# 2) Select the destination context
#
# A full path to the list of items that will be insanced MUST to be included below.
#
##########################################

# PUT YOUR FULL URL's TO THE ITEMS YOU WANT TO INSTANCE BELOW.
# IF YOU PUT IN MORE THAN ONE, THEY WILL BE INSTANCED IN A ROTATING ORDER.

items_to_attach = [
"project://LAYOUT/main/ACTIVE/haze/polygrid",
"project://LAYOUT/main/ACTIVE/haze/polysphere",
]


def attach():

    scale = "1.0"

    offset_x = 0
    offset_y = 0
    offset_z = 0

    item_count = len(items_to_attach)

    selected = list()
    for i in range(ix.selection.get_count()):
        selected.append(ix.selection[i])

    DESTINATION_CTX = selected[-1].get_full_name()
    item_url = selected[-2].get_full_name()
    selected = selected[:-2]

    locators = dict()
    for item in selected:
        locators[item.get_name()] = [item]

    item_counter = 0
    for locator in locators.keys():

        # Get the current light url
        item_url = items_to_attach[item_counter]
        item_counter += 1
        if item_counter > item_count - 1:
            item_counter = 0

        # Create an instance in a specific context
        instance_name = ix.cmds.CreateInstancesTo([item_url], DESTINATION_CTX)[0]
        instance = ix.item_exists(instance_name)

        # Localize the out node transforms and parent
        ix.cmds.LocalizeAttributes([DESTINATION_CTX + "/" + instance.get_name() + ".translate"], True)
        ix.cmds.LocalizeAttributes([DESTINATION_CTX + "/" + instance.get_name() + ".rotate"], True)
        ix.cmds.LocalizeAttributes([DESTINATION_CTX + "/" + instance.get_name() + ".scale"], True)
        ix.cmds.LocalizeAttributes([DESTINATION_CTX + "/" + instance.get_name() + ".parent"], True)

        # Set the parent to the original locator
        ix.cmds.SetParent([DESTINATION_CTX + "/" + instance.get_name() + ".parent"], [locators[locator][0].get_full_name()], [0])

        # Zero out the transforms
        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".translate[0]"], ["0.0"])
        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".translate[1]"], ["0.0"])
        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".translate[2]"], ["0.0"])

        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".rotate[0]"], ["0.0"])
        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".rotate[1]"], ["0.0"])
        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".rotate[2]"], ["0.0"])

        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".scale[0]"], [scale])
        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".scale[1]"], [scale])
        ix.cmds.SetValues([DESTINATION_CTX + "/" + instance.get_name() + ".scale[2]"], [scale])




attach()

Re: How to batch add parent constraints?

Unread postPosted: Wed Apr 14, 2021 4:11 am
by weindy
Hello!

I have tested the above scripts, and it worked perfect! Thanks a lot :lol: :lol:

but still wondering...the step for selecting lcator, can change into matching name?

the maya mel way is: ls -sl "*matched_name*"

Cheers!

Re: How to batch add parent constraints?

Unread postPosted: Thu Apr 15, 2021 4:34 am
by bvz
So you want to have it automatically select the locators based on their name?

Something like: select any items anywhere in the project that have "matched_name" somewhere in their name?

That should be doable. Let me try coding something up and and I can paste it in here.

If I misunderstood, let me know.

Re: How to batch add parent constraints?

Unread postPosted: Thu Apr 15, 2021 8:48 am
by bvz
Just another thought (since I don't have time to play with the script right now).

You could just hit "f3" and search for your "matched_name" item, select the matching items in the search window, select the destination context and run the script. That would get you the same behavior you were hoping for from the script itself (albeit with a few more manual steps, but not too many)

Re: How to batch add parent constraints?

Unread postPosted: Fri Apr 16, 2021 3:15 am
by weindy
Yes, automatically will be perfect, but the script already saved me much of time now!

I think with F3 searching way is enough.

Sorry for take your time too much, and thanks for sharing again!

Re: How to batch add parent constraints?

Unread postPosted: Fri Apr 16, 2021 10:30 pm
by bvz
I'm happy to help. As soon as I have a moment I will still try to set it up with the search code though and post it here.