Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to Get the custom Data of a Prim Material #147

Closed
tushar-s-mpcfilm opened this issue Jan 9, 2020 · 9 comments
Closed

How to Get the custom Data of a Prim Material #147

tushar-s-mpcfilm opened this issue Jan 9, 2020 · 9 comments
Labels

Comments

@tushar-s-mpcfilm
Copy link

Hi,

we are trying to get the custom data to the material using prim.GetCustomData()
It gives a VtDictionary but we are not able to get the data inside it since it doesn't provide anyways to access it or i am just not able to find it.

We tried we the same way in python and it worked.

Can anyone point in correct direction?

Thanks in advance.

@judubu
Copy link
Contributor

judubu commented Jan 9, 2020

Hi Tushar,

I'm not sure if your issue is related to a bug in the API or that you didn't find the API to read the data from the VtDictionary.

VtDictionary is a direct wrap of the pxr::base::vt::VtDictionary and you can find the CS interface here: https://github.com/Unity-Technologies/usd-unity-sdk/blob/master/src/USD.NET/generated/pxr/base/vt/VtDictionary.cs

Use GetValueAtPath("your_key") to get the data stored at key "your_key", find("your_key") to get an iterator to the pair matching the key, but you can also iterate the dict using begin and end.

We are using it here

var modelInfo = new VtDictionary();
if (!modelApi.GetAssetInfo(modelInfo)) {
return;
}
info.isModel = true;
var valName = modelInfo.GetValueAtPath("name");
var valVersion = modelInfo.GetValueAtPath("version");
var valIdentifier = modelInfo.GetValueAtPath("identifier");
if (valIdentifier != null && !valIdentifier.IsEmpty()) {
info.modelAssetPath = UsdCs.VtValueToSdfAssetPath(valIdentifier).GetAssetPath().ToString();
}
if (valName != null && !valName.IsEmpty()) {
info.modelName = UsdCs.VtValueTostring(valName);
}
if (valVersion != null && !valVersion.IsEmpty()) {
info.modelVersion = UsdCs.VtValueTostring(valVersion);
}

Note that the values you'll get will be of type VtValue and you will have to convert them to a usable C# type with the corresponding VtValueTo*** function.

If that doesn't help can you provide us the usd file and the code sample you're using.

Thanks

@jcowles
Copy link
Contributor

jcowles commented Jan 9, 2020

You can also read custom data using the high level API.

I created a custom data key called "CustomKey":
image

Next create a class to read that data:

    [System.Serializable]
    public class MyCustomData : SampleBase
    {
        [CustomData]
        public string CustomKey;
    }

Open the scene as usual:

Scene scene = Scene.Open(@"D:\usd\Kitchen_set\Kitchen_set.usd");

And read the data:

var sample = new MyCustomData();
scene.Read("/Kitchen_set", sample);

// Prints "Custom value"
Debug.Log(sample.CustomKey);

@pramod-s-mpcfilm
Copy link

@judubu I have attached the usd file which we are using. I have stripped down the content to very basic data with relevant information. But the structure would be the same for the rest of our full data.
If you can get the custom data values from custom "parameters" content, than it is what we are trying to retrieve.
USDMatFile.txt

@judubu
Copy link
Contributor

judubu commented Jan 13, 2020

All right I see, you have nested VtDictionaries. They don't automatically convert like they do in python, there are no VtValueToVtDict available and VtDictionaryGet is not implemented ...
Tricky one.
I'll see what I can do

@jcowles
Copy link
Contributor

jcowles commented Jan 13, 2020

Nested types should also work fine, here's an example with three different ways of reading the data:

using UnityEngine;
using USD.NET;
using Unity.Formats.USD;

[ExecuteInEditMode]
public class TEst : MonoBehaviour
{
    [System.Serializable]
    public class SurfaceParams : SampleBase
    {
        // You can either use a namespace or nested "Sample" objects.
        // Using nested objects probably better matches the data, but here
        // I'm just using the UsdNamespace attribute because it's simpler.
        [UsdNamespace("material:parameters")]
        [CustomData]
        public int Bake_Bake_DiffuseColor;
    }

    void OnEnable()
    {
        InitUsd.Initialize();
        Scene scene = Scene.Open(@"USDMatFile.usda");
        var sample = new SurfaceParams();
        var prim = scene.GetPrimAtPath("/root/materials/pxrSurface/basicSurface_mat");


        //
        // READ FROM PRIM DIRECTLY
        //
        Debug.Log(pxr.UsdCs.VtValueToint(prim.GetCustomDataByKey(new pxr.TfToken("material:parameters:Bake_Bake_DiffuseColor"))));

        //
        // READ FROM CUSTOM DATA
        //
        var dataDict = prim.GetCustomData();
        Debug.Log(pxr.UsdCs.VtValueToint(dataDict.GetValueAtPath("material:parameters:Bake_Bake_DiffuseColor")));

        //
        // READ VIA HIGH LEVEL SERIALIZATION API
        //
        scene.Read<SurfaceParams>("/root/materials/pxrSurface/basicSurface_mat", sample);
        scene.Close();
        Debug.Log(sample.Bake_Bake_DiffuseColor);
    }

}

@jcowles
Copy link
Contributor

jcowles commented Jan 13, 2020

Here's an example using a nested object, which is probably nice when you have so many attributes to read:

using UnityEngine;
using USD.NET;
using Unity.Formats.USD;

[ExecuteInEditMode]
public class TEst : MonoBehaviour
{

    [System.Serializable]
    public class MaterialCustomData : SampleBase
    {
        [UsdNamespace("material")]
        [CustomData]
        public string style;

        [UsdNamespace("material:parameters")]
        [CustomData]
        public ParamContainer parameters = new ParamContainer();

        [UsdNamespace("material:terminals")]
        [CustomData]
        public TerminalContainer terminals = new TerminalContainer();

        public class ParamContainer : SampleBase
        {
            [CustomData] public int Bake_Bake_DMFP;
            [CustomData] public int Bake_Bake_DiffuseColor;
            [CustomData] public int Bake_Bake_Diffuse_Roughness;
            [CustomData] public int Bake_Bake_ExtinctionCoeff;
            [CustomData] public int Bake_Bake_SPEC2Mask;
            [CustomData] public int Bake_Bake_SPECR;
            [CustomData] public int Bake_Bake_SPECR2;
            [CustomData] public int Bake_Bake_TransmissionColor;
            [CustomData] public int Bake_Bake_ior;
        }

        public class TerminalContainer : SampleBase
        {
            [CustomData] public string prmanBxdf;
            [CustomData] public string prmanDisplacement;
        }
    }

    void OnEnable()
    {
        InitUsd.Initialize();
        Scene scene = Scene.Open(@"USDMatFile.usda");

        var matData = new MaterialCustomData();
        scene.Read("/root/materials/pxrSurface/basicSurface_mat", matData);
        Debug.Log(matData.parameters.Bake_Bake_DiffuseColor);
        Debug.Log(matData.terminals.prmanBxdf);

        scene.Close();
    }
}

@pramod-s-mpcfilm
Copy link

pramod-s-mpcfilm commented Jan 14, 2020

@jcowles Thanks for your input which temporary worked out for us. But as I mentioned previously, I had stripped out lot of data to send it to you people and I feel that adding all the custom key & data parameters coming out of Katana material files (>2500 custom key & data) into the class/schema will not be ideal.
So any other alternate which can provide me very large of custom key & data similar to what python or C++ USD sdk provides will be very much helpful.

And as our company have certain policy which restrict us from give out details on open forum, any possibility that I can contact you over the e-mail for future communication?

Thanks,
Pramod S

@jcowles
Copy link
Contributor

jcowles commented Apr 9, 2020

I believe we've already followed up offline, but yes, feel free to reach out directly jcowles@unity3d

@jcowles
Copy link
Contributor

jcowles commented Oct 1, 2020

Given that this issue has been dormant for quite a while, I'm going to close this out -- but please reopen if you'd like to pursue it!

@jcowles jcowles closed this as completed Oct 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants