Announcement

Collapse
No announcement yet.

Alembic workflow for Maya/Arnold?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Alembic workflow for Maya/Arnold?

    Hello,

    I am looking at exporting trees for Maya 2020/Arnold 6 from Speedtree Cinema v8.4.2 with an Alembic-only pipeline. (Accepting the limitations noted in the ST docs about bones being FBX only).

    This seems to mostly work, with a few caveats:
    1. The alembic caches generated seem to use the same name for both the transform and mesh nodes, which makes Maya more challenging to operate as the names within the namespace are not unique (ideally the mesh nodes would be named something like X_shape). This seems to cause difficulties for the SpeedTreeImporter.py script resulting in the '.aiOpaque' flags failing to apply. I have described a small tweak below that seems to work for me.
    2. I'm a little confused about the usage of blend_ao. AFAICT (from other forum posts - see topics #4353, #6643, #7914, #8047), blend is in the U coord, and ao is in the V coord - which matches up with the usage of an aiUserDataVec2, but the alembic file seems to be using a float32_t[3] for blend_ao, rather than a float32_t[2] like uv uses?
    3. Also, the Maya AbcImport module doesn't seem to handle importing blend_ao as a UV set? (Though it does import as a UVset correctly from FBX). Skimming the Maya AbcImport module, it looks like it doesn't currently handle any kind of CompoundProperty's in arbGeomParams, so I'm not sure this could ever be expected to work with an Alembic pipeline currently?
    An example snippet from abcecho showing (1) see /Sample_Palm/Trunk/Trunk vs /Sample_Palm/Trunk, and (2) the arbGeomParams including blend_ao vs uv:
    Code:
    AbcEcho for Alembic 1.7.14 (built Aug 31 2020 18:57:22)
    sample_palm_abc3/Sample_Palm.abc
      (file doesn't have any ArchiveInfo)
    
    Object name=/Sample_Palm
      CompoundProperty name=.xform;schema=AbcGeom_Xform_v3
        ScalarProperty name=.inherits;interpretation=;datatype=bool_t;arraysize=1;numsamps=1
        ScalarProperty name=.ops;interpretation=;datatype=uint8_t;arraysize=1;numsamps=1
        ScalarProperty name=.vals;interpretation=;datatype=float64_t[3];arraysize=3;numsamps=1
    Object name=/Sample_Palm/Trunk
      CompoundProperty name=.xform;schema=AbcGeom_Xform_v3
        ScalarProperty name=.inherits;interpretation=;datatype=bool_t;arraysize=1;numsamps=1
        ScalarProperty name=.ops;interpretation=;datatype=uint8_t;arraysize=1;numsamps=1
        ScalarProperty name=.vals;interpretation=;datatype=float64_t[3];arraysize=3;numsamps=1
        ScalarProperty name=isNotConstantIdentity;interpretation=;datatype=bool_t;arraysize=1;numsamps=1
    Object name=/Sample_Palm/Trunk/Trunk
      CompoundProperty name=.geom;schema=AbcGeom_PolyMesh_v1
        ScalarProperty name=.selfBnds;interpretation=box;datatype=float64_t[6];arraysize=6;numsamps=1
        ArrayProperty name=P;interpretation=point;datatype=float32_t[3];arraysize=3810;numsamps=1
        ArrayProperty name=.faceIndices;interpretation=;datatype=int32_t;arraysize=20322;numsamps=1
        ArrayProperty name=.faceCounts;interpretation=;datatype=int32_t;arraysize=6774;numsamps=1
        CompoundProperty name=.arbGeomParams;schema=
          CompoundProperty name=blend_ao;schema=
            ArrayProperty name=.vals;interpretation=rgb;datatype=float32_t[3];arraysize=3937;numsamps=1
            ArrayProperty name=.indices;interpretation=;datatype=uint32_t;arraysize=20322;numsamps=1
          CompoundProperty name=geom_type;schema=
            ArrayProperty name=.vals;interpretation=;datatype=string;arraysize=7;numsamps=1
            ArrayProperty name=.indices;interpretation=;datatype=uint32_t;arraysize=6774;numsamps=1
          CompoundProperty name=hierarchy;schema=
            ArrayProperty name=.vals;interpretation=;datatype=string;arraysize=9339;numsamps=1
            ArrayProperty name=.indices;interpretation=;datatype=uint32_t;arraysize=6774;numsamps=1
          ArrayProperty name=hierarchy_level;interpretation=;datatype=uint16_t;arraysize=6774;numsamps=1
          CompoundProperty name=anchor;schema=
            ArrayProperty name=.vals;interpretation=matrix;datatype=float32_t[16];arraysize=9339;numsamps=1
            ArrayProperty name=.indices;interpretation=;datatype=uint32_t;arraysize=6774;numsamps=1
          CompoundProperty name=spine;schema=
            ArrayProperty name=.vals;interpretation=;datatype=string;arraysize=9339;numsamps=1
            ArrayProperty name=.indices;interpretation=;datatype=uint32_t;arraysize=6774;numsamps=1
        CompoundProperty name=uv;schema=
          ArrayProperty name=.vals;interpretation=vector;datatype=float32_t[2];arraysize=3937;numsamps=1
          ArrayProperty name=.indices;interpretation=;datatype=uint32_t;arraysize=20322;numsamps=1
        CompoundProperty name=N;schema=
          ArrayProperty name=.vals;interpretation=normal;datatype=float32_t[3];arraysize=3937;numsamps=1
          ArrayProperty name=.indices;interpretation=;datatype=uint32_t;arraysize=20322;numsamps=1
    Tweak to SpeedTreeImporter.py for (1):
    Code:
    #Around line 185 currently, there is
    aShapes = mc.listConnections(newset + ".dagSetMembers")
    
    #Replace this line with the several below which use listRelatives to find only the shape nodes with full paths
    aAttachedGeo = mc.listConnections(newset + ".dagSetMembers")
    aShapes = []
    for geo in aAttachedGeo:
      aShapes += mc.listRelatives(geo, path=True, shapes=True)
    Thanks in advance.

  • #2
    Hello,

    The alembic caches generated seem to use the same name for both the transform and mesh nodes
    I have not seen this being a problem before, but I will look into it. Adding "shape" to the name is relatively innocuous, so I don't see why we couldn't do that always. But your code fix looks good too. Maybe we can roll in both.


    the alembic file seems to be using a float32_t[3] for blend_ao, rather than a float32_t[2] like uv uses?
    This is actually a consequence of trying to support lots of different apps. Blend_AO is a C3f color so it will import into the most apps as possible. I don't recall which was giving us trouble as a UV, but I would guess Max. It would be great if we could stick the blend value into vertex color alpha, but not all apps import a 4 channel color.


    Also, the Maya AbcImport module doesn't seem to handle importing blend_ao as a UV set?
    I believe it comes in as a color set in Maya. aiUserDataVec2 just looks things up by name, so it should be able to find it.

    It could be that Alembic support is much better now (or at least has changed a little) since we last updated the scripts. We are about to really start testing the exporting system for SpeedTree v9, so I have logged your reports and fixes.


    Thanks for the report

    Comment


    • #3
      That all sounds good, thanks for taking a look - it's always interesting to know why as well as what.

      Originally posted by Greg Croft View Post
      I believe it comes in as a color set in Maya. aiUserDataVec2 just looks things up by name, so it should be able to find it.
      Just to follow up on this bit:
      - When exporting->importing a tree as FBX to Maya (2020r2), I see 2 UV sets called "uv0" and "blend_ao", and 1 colour set called "color(RGBA)"
      - When exporting->importing a tree as Alembic to Maya (2020r2), I see 1 UV set called "map1" and 0 colour sets?

      Also a heads up for when you are next testing this stuff: if the ST8 alembic export setting "extra attributes" is enabled, Maya's AbcImport will emit some (harmless?) warnings "Unsupported attr, skipping: hierarchy_level uint16_t[1]", even though it seems to manage to add hierarchy_level as an attribute to the meshes.

      Originally posted by Greg Croft View Post
      It could be that Alembic support is much better now (or at least has changed a little)
      "Better" is definitely a relative term here...

      (Note to self: maybe I should fix this stuff in the upstream Alembic plugin)

      Comment


      • #4
        In FBX it is an actual UV.

        In that last test, were you using our script or doing a direct alembic import? In Maya you need to use the -rcs / recreateAllColorSets option to get all of them (for some reason). Our latest script does this, but perhaps, while you are using the latest Modeler, you have an older script?

        I found mention of Houdini having to change how they saved colors into Alembic in order to get them to load in Maya even without that option. I may have to try to figure out what they did.

        Comment


        • #5
          Originally posted by Greg Croft View Post
          In that last test, were you using our script or doing a direct alembic import? In Maya you need to use the -rcs / recreateAllColorSets option to get all of them (for some reason).
          Good guess. I did indeed do a direct import for that quick test (which didn't include -rcs, as this in only available when running the AbcImport mel command).

          I can confirm that using "AbcImport -rcs" (as included in the ST8.4.2 import script) does indeed bring a blend_ao colourset in to Maya. Yay!

          Sadly, the trunk of the Sample_Palm is still completely invisible in a quick Arnold render. Some further digging around shows that coloursets aren't actually exported to Arnold by default. Each shape node needs the "Export Vertex Colours" option (in the Arnold-specific section enabled), at which point the aiUserDataVec2 does indeed pick up the data from blend_ao as intended.

          Another quick-and-dirty patch for the SpeedTreeImporter.py:
          Code:
          #around line 314, just after the aiUserDataVec2 node's and related mc.connectAttrs add
          for shape in aShapes:
            if not shape.endswith("_Spine"):
              mc.setAttr(shape + ".ai_expcol", 1)

          Finally, given I am in this region of the code lets ask: is there a particular reason for using the 'hidden' aiUserDataVec2 node, rather than an aiUserDataColor node (at least with alembic imports, maybe this is necessary to work with UV Sets from fbx)?

          So, I suppose lets polish up with a final tweak of:
          Code:
          #around line 310-134, replace the userdata = mc.shadingNode() and mc.connectAttr blob with
          userdata = mc.shadingNode("aiUserDataColor", asUtility = True)
          mc.setAttr(userdata + ".attribute", "blend_ao", type="string")
          mc.connectAttr(userdata + ".outColorR", shader + ".opacityR")
          mc.connectAttr(userdata + ".outColorR", shader + ".opacityG")
          mc.connectAttr(userdata + ".outColorR", shader + ".opacityB")

          Anyway, this workflow seems to be functioning nicely now, so I suppose I should move on to more interesting trees than Sample_Palm...

          Thanks for all your help.

          Comment


          • #6
            Hello,

            I'll definitely add ai_expcol. We had to do a similar thing when they added aiOpaque.

            You got it on why use aiUserDataVec2 - it works for any user data, uv or color. But if you know you're always using Alembic, what you changed is absolutely fine. I'm just glad you're finding your way around the script easily.

            Comment

            Working...
            X