Instancing Maya assets

   6310   7   3
User Avatar
Member
83 posts
Joined: April 2014
Offline
I am just getting into Houdini Engine for Maya/Unreal, and am trying to create an instancer in those DCCs for production. It was pretty easy for Unreal but for some reason Maya seems to be a bit more tricky. I have been learning a lot on this forum, but my lack of Maya experience lately still has be with some questions, which I was wondering if I could have some help with.

We are trying to instance imported assets through the Houdini Engine in Maya, either as DAG objects or with Maya's instancer.

1. When baking out instances, there is a preference I have for the Asset Options (Ungroup on Bake = Off, Use Instancer Node = On…). Is there a way to set defaults so artists don't have to change that every time before they bake out their instances?

2. What are the advantages of using the instance Obj node vs. copy Sop with Pack Geo Before Copying turned on?

3. I saw you can add a custom attribute to the instances using the copy Sop (can you do the same with the instancer node?). Where can I found the output attributes in Maya for my instances?

4. It seems like whenever I bake an asset with Instances (both when Use Instancer Node is On and Off), the instanced objects loose their name. Is there a way to maintain their original name? as right now they seem to all get the name of the last node in the output sop.

5. Is there a way to create an attribute to instance a specific DAG object? In the Unreal engine plugin, you could specify the “unreal_instance” and point that to something like “StaticMesh'/PATH/OBJECTNAME'”. Is there a way to do the same in Maya?

6. One of the assets posted on the forum was helpful, however I saw that when Use Instancer Node is checked on and baked, nothing is seemed to be baked out. I know this isn't my node, but I was wondering what could be causing the node to not be baked properly. (test_packed_with_string.hda)

Sorry for all the questions, but this is helping a lot.
Edited by Tyler Britton2 - May 27, 2020 14:56:51

Attachments:
test_packed_with_string.hda (18.7 KB)

User Avatar
Staff
463 posts
Joined: Aug. 2019
Offline
Hi Tyler,

1) Currently there is no way to do this out of the box. There is an open RFE for this however, #75623. Right now, the only option is to edit AEhoudiniAssetTemplate.mel

2) “Pack Geometry Before Copying” packs the geometry inside of Houdini. “Use Instancer Node” sets how the packed geometry is brought into Maya.

See the following for more information:

For best performance in both applications, enabling both “Pack Geometry Before Copying” and “Use Instancer Node” is recommended.

3) You can retrieve the attributes from the outputPartExtraAttribute* attributes on the Houdini Asset node. In the case of the attached HDA, if “Pack Geometry Before Copying” and “Use Instancer Node” is enabled:

Get the name of the first attribute:
getAttr test_packed_with_string1.outputObjects[0].outputGeos[0].outputParts[0].outputPartExtraAttributes[0].outputPartExtraAttributeName;

Get the values of the first attribute:
getAttr test_packed_with_string1.outputObjects[0].outputGeos[0].outputParts[0].outputPartExtraAttributes[0].outputPartExtraAttributeData;

More information about the Houdini Asset attributes can be found here: https://www.sidefx.com/docs/maya/_maya__nodes.html#Maya_Nodes_HoudiniAsset [www.sidefx.com]

4) This is not currently possible, but has come up in the past. I'll file an RFE.

5) What is the intended use case for this? So that you can utilize Houdini to create the transforms and then connect a maya node to each?

6) Thanks for the report. I'll file a bug for it.
User Avatar
Member
83 posts
Joined: April 2014
Offline
johnmather
2) “Pack Geometry Before Copying” packs the geometry inside of Houdini. “Use Instancer Node” sets how the packed geometry is brought into Maya.
Thanks John. My question was a actually a little different, I wanted to know if there was a preference of using the Copy To Points Sop vs. using the Instance object sop inside of the HDA for instancing. It looks like the Copy To Points sop is better because you can Pack before instancing?


johnmather
4) This is not currently possible, but has come up in the past. I'll file an RFE.
This would be huge. It is hard to track assets being instances after they are baked out.

johnmather
6) Thanks for the report. I'll file a bug for it.
Thank you. I am having the same situation for another asset I made. Any progress on this bug would be helpful.

johnmather
5) What is the intended use case for this? So that you can utilize Houdini to create the transforms and then connect a maya node to each?
There is no specific use case, it is just in case I want to hard wire a specific DAG object to instance, then I could ideally create an attribute to use to instance a specific DAG object.

Something holding me back from using the Engine in Maya is that even though you can instances DAG objects, once you makes them out they loose their name (4)), as well as some inconsistencies with the engine not baking the objects (6)). As a workaround I was trying to see if I could store the DAG object string along with the the transform data then just recreate the DAG objects being instanced seperately, similar to what Use Instrancer Node turned off does. I know this isnt ideal, but it would be a temporary fix to for 4) and 6), which are the main issues I am running into. I have a way to get the transform data for the instances, I would just need the DAG names.
Here is what I found to get the instance transforms:
from maya import OpenMaya as om
from maya import OpenMayaFX as omfx

sel = om.MSelectionList()
sel.add("instancer1")
dag = om.MDagPath()
sel.getDagPath(0, dag)

fn = omfx.MFnInstancer(dag)
count = fn.particleCount()
for i in xrange(count):
    paths = om.MDagPathArray()
    matrix = om.MMatrix()
    fn.instancesForParticle(i, paths, matrix)
    print i
    print [paths[j].fullPathName() for j in xrange(paths.length())]
    print [matrix(j/4, j%4) for j in xrange(16)]

Please let me know if there is a better way.
Edited by Tyler Britton2 - May 27, 2020 19:37:02
User Avatar
Staff
463 posts
Joined: Aug. 2019
Offline
Hi Tyler,

The following code will extract the “test_string” attribute for each instance. You can modify the HDA and the attrvariable to extract a DAG path.

from maya import OpenMaya as om
from maya import OpenMayaFX as omfx

from maya import cmds

sel = om.MSelectionList()
sel.add("instancer1")
dag = om.MDagPath()
sel.getDagPath(0, dag)

fn = omfx.MFnInstancer(dag)
count = fn.particleCount()

attr = 'test_string'

for i in xrange(count):
    paths = om.MDagPathArray()
    matrix = om.MMatrix()
    fn.instancesForParticle(i, paths, matrix)

    for j in xrange(paths.length()):
        shape = paths[j].fullPathName()
        hAsset = cmds.listConnections(shape + '.inMesh', type='houdiniAsset')

        attrData = None

        if len(hAsset) < 1:
            continue

        hAsset = hAsset[0]

        extraAttrsAttr = hAsset + '.outputObjects[0].outputGeos[0].outputParts[0].outputPartExtraAttributes'
        nExtraAttrs = cmds.getAttr(extraAttrsAttr, s=True)

        for k in xrange(nExtraAttrs):
            extraAttrAttr = '%s[%d]' % (extraAttrsAttr, k)
            extraAttrName = cmds.getAttr(extraAttrAttr + '.outputPartExtraAttributeName')

            if extraAttrName == attr:
                attrData = cmds.getAttr(extraAttrAttr + '.outputPartExtraAttributeData')[i]
                break

        print i
        print shape
        print hAsset
        print '%s = "%s"' % (attr, attrData)
        print [matrix(j/4, j%4) for j in xrange(16)]

In regards to the Copy To Points SOP vs. using the Instance SOP, the Instance SOP is recommended as it creates packed primitives. The Copy To Points SOP will create unique geometry per copy.
User Avatar
Member
83 posts
Joined: April 2014
Offline
Thanks John, this is some magic, and exactly what I need.


I have noticed some more assets seem to not be baking out the instances, similar to my previous post. It is happening on our production otl, but also on the one Andrew posted here https://www.sidefx.com/forum/topic/35446/. [www.sidefx.com] I will attach it to the post. It might be a bug report or something that I am doing wrong. I am using 18.0.348 with Maya 2020.

Attachments:
simple_instance.otl (11.9 KB)

User Avatar
Member
83 posts
Joined: April 2014
Offline
One other quick question. While the code above works, the DAG path for the specific objects I am instancing is still unknown. I think the purpose of the “shape” (shape = paths.fullPathName()) in the code above was to get the DAG instances, however it seems to get the names of the objects once they have been converted inside the Houdini asset (|output0_1|output0_1Shape instead of something like |treeAssetObject_1|treeAssetObject__1Shape). To get ideally what I need I thought of two options, but neither quite what I wanted to get through.

1) Getting the DAG inside the HDA. I was wondering if there was something built in for this? I Saw that there is “maya_source_dag” as a detail attribute, however I am loading in my assets through an Object Merge, so since there is no source object that didn't work for me. I guess I could also do some Maya cmds with Python sop inside the HDA, but I was trying to stay away from that.

2) I was also trying to get the name from the parm that the Object Merge creates on the top level which am plugging my asset objects into. It gives something I could use (|treeAssetObject_1|treeAssetObject_1), and is pretty close to what I need. However, when I tried to eval the parm I didn't get what I was looking for.
# PYTHON
import os

# Maya
import maya.cmds as cmds
import maya.mel as mel

# Get the currently selected items
sel = cmds.ls(selection=True, uuid=True)
for asset in sel:
    curRoot = cmds.ls(asset)[0]
    parmName = ""
    print cmds.getAttr(curRoot+'.houdiniAssetParm_objpath1')
Returns an error. I would expect something to return the input when the input (|treeAssetObject_1|treeAssetObject_1). I checked and made sure that it is the point to the HDA. I can specify other parms, however for some reason objpath1 for some reason does not work, and I am pretty sure that it's the correct name.

Thanks for your help again.
Thanks for your help again.
Edited by Tyler Britton2 - May 29, 2020 12:59:28
User Avatar
Staff
463 posts
Joined: Aug. 2019
Offline
Tyler Britton2
I have noticed some more assets seem to not be baking out the instances, similar to my previous post. It is happening on our production otl, but also on the one Andrew posted here https://www.sidefx.com/forum/topic/35446/. [www.sidefx.com] I will attach it to the post. It might be a bug report or something that I am doing wrong. I am using 18.0.348 with Maya 2020.
This is correct from the plugins view, as there is really only a single sphere and cube when instanced. This may or may not be expected behaviour however. In order to get this to work, you can uncheck “Use Instancer”, and then bake.

Regarding “maya_source_dag”, that attribute was removed in 16.0.424.

How are you providing your instance objects to the HDA? Could you please attach an example?
User Avatar
Member
1 posts
Joined: Nov. 2020
Offline
I'm trying to do something similar but I am stuck.. I would like to create an instancer that needs as input the geo where to scatter and which objects to scatter.. it's working in Houdini but when I use it in Maya as a digital asset, it doesn't work.. I am going to attach the hip, hda files and a test geo where to scatter on.. experimenting around I had different errors like: the instance attribute on the point is not a valid attribute or for the geo that I was giving as an input "Error: Invalid argument given: This node has no object." any help would be really appreciated


Image Not Found


Image Not Found


Image Not Found
Edited by giuseppeseda - Feb. 28, 2022 13:14:50

Attachments:
ground.abc (343.2 KB)
GS_OSMbuildingscatter.hda (39.5 KB)
scatterBuilding.hip (1.3 MB)

  • Quick Links