# Flattening loses some valid material bindings

**URL:** <https://forum.aousd.org/t/flattening-loses-some-valid-material-bindings/883>\
**Category:** USD\
**Created:** [November 1, 2023, 11:46pm UTC](https://forum.aousd.org/t/flattening-loses-some-valid-material-bindings/883 "2023-11-01T23:46:45Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![DaKrunch](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/dakrunch/32/310_2.png) [@DaKrunch](https://forum.aousd.org/u/DaKrunch)\
**Post date:** [November 1, 2023, 11:46pm UTC](https://forum.aousd.org/t/flattening-loses-some-valid-material-bindings/883/1 "2023-11-01T23:46:45Z")

</div>

Hi there  
I ran into a weird behavior triggered by exporting a stage - which comes with a flattening step.  
Material bindings in my instanced prims are lost - or rather left unset, dangling, sad rel’s.

consider this snippet

```auto
#pragma warning(disable: 4267)

#include <pxr/usd/usd/stage.h>
#include <pxr/usd/usdGeom/mesh.h>
#include <pxr/usd/usdGeom/scope.h>
#include <pxr/usd/usdShade/material.h>
#include <pxr/usd/usdShade/materialBindingAPI.h>

// When these converters get stabilized, remove this test as it's a duplicate of what's in lagrange
TEST(Meshio, instanceMaterials)
{
    // Create initial stage
    pxr::UsdStageRefPtr stageOriginal = pxr::UsdStage::CreateInMemory();

    // Create default prim
    pxr::UsdPrim rootPrim = stageOriginal->DefinePrim(pxr::SdfPath("/MyAsset"));
    stageOriginal->SetDefaultPrim(rootPrim);

    // create material
    pxr::UsdShadeMaterial usdMaterial = pxr::UsdShadeMaterial::Define(stageOriginal, pxr::SdfPath("/MyAsset/material"));

    // create mesh to be instanced
    pxr::UsdGeomMesh usdMesh = pxr::UsdGeomMesh::Define(stageOriginal, pxr::SdfPath("/MyMesh/MeshToInstance"));
    // bind material to usdMesh
    auto materialBindingAPI = pxr::UsdShadeMaterialBindingAPI::Apply(usdMesh.GetPrim());
    bool result = materialBindingAPI.Bind(usdMaterial);
    // we don't want this to be left as a corpse laying about after flattening
    usdMesh.GetPrim().SetActive(false);

    // create instance
    pxr::UsdGeomScope instanceOfMesh = pxr::UsdGeomScope::Define(stageOriginal, pxr::SdfPath("/MyAsset/InstanceOfMesh"));
    instanceOfMesh.GetPrim().GetReferences().AddReference("", usdMesh.GetPrim().GetPath());
    instanceOfMesh.GetPrim().SetInstanceable(true);
    instanceOfMesh.GetPrim().SetActive(true);

    // clear metadata
    stageOriginal->GetRootLayer()->Export("C:/Users/Davide/Documents/export_unflattened.usda"); // materials are bound
    stageOriginal->Export("C:/Users/Davide/Documents/export_flattened.usda"); // materials bindings are lost
}

```

the resulting files show this weird behavior. Unflattened is fine:

```auto
#usda 1.0
(
    defaultPrim = "MyAsset"
)

def "MyAsset"
{
    def Material "material"
    {
    }

    def Scope "InstanceOfMesh" (
        active = true
        instanceable = true
        prepend references = </MyMesh/MeshToInstance>
    )
    {
    }
}

def "MyMesh"
{
    def Mesh "MeshToInstance" (
        active = false
        prepend apiSchemas = ["MaterialBindingAPI"]
    )
    {
        rel material:binding = </MyAsset/material>
    }
}

```

but flattened loses the binding

```auto
#usda 1.0
(
    defaultPrim = "MyAsset"
    doc = """Generated from Composed Stage of root layer 
"""
)

over "Flattened_Prototype_1"
{
}

def "MyAsset"
{
    def Material "material"
    {
    }

    def Scope "InstanceOfMesh" (
        active = true
        apiSchemas = ["MaterialBindingAPI"]
        instanceable = true
        add references = </Flattened_Prototype_1>
    )
    {
        rel material:binding
    }
}

def "MyMesh"
{
}

```

Any idea of what I may be doing wrong? or is flattening broken?

---

<div class="post-metadata">

**Author:** ![DaKrunch](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/dakrunch/32/310_2.png) [@DaKrunch](https://forum.aousd.org/u/DaKrunch)\
**Post date:** [November 1, 2023, 11:56pm UTC](https://forum.aousd.org/t/flattening-loses-some-valid-material-bindings/883/2 "2023-11-01T23:56:57Z")

</div>

Ok it appears that moving the binding to the instancing prim does work.  
Seems like in general having relationships to anything outside the instanced tree is a bad idea. (Thanks Spiff)
