void CollectSubAssets(Subassets subassets, AlembicTreeNode node)
        {
            var mesh = node.GetAlembicObj <AlembicMesh>();

            if (mesh != null)
            {
                var sum = mesh.summary;
                if (mesh.summary.topologyVariance == aiTopologyVariance.Heterogeneous)
                {
                    VaryingTopologyMeshNames.Add(node.gameObject.name);
                }
                else if (mesh.sampleSummary.splitCount > 1)
                {
                    SplittingMeshNames.Add(node.gameObject.name);
                }
            }

            int submeshCount = 0;
            var meshFilter   = node.gameObject.GetComponent <MeshFilter>();

            if (meshFilter != null)
            {
                var m = meshFilter.sharedMesh;
                submeshCount = m.subMeshCount;
                m.name       = node.gameObject.name;
                subassets.Add(node.abcObject.abcObject.fullname, m);
            }

            var renderer = node.gameObject.GetComponent <MeshRenderer>();

            if (renderer != null)
            {
                var mats = new Material[submeshCount];
                for (int i = 0; i < submeshCount; ++i)
                {
                    mats[i] = subassets.defaultMaterial;
                }
                renderer.sharedMaterials = mats;
            }

            var apr = node.gameObject.GetComponent <AlembicPointsRenderer>();

            if (apr != null)
            {
                var cubeGO = GameObject.CreatePrimitive(PrimitiveType.Cube);
                apr.sharedMesh = cubeGO.GetComponent <MeshFilter>().sharedMesh;
                DestroyImmediate(cubeGO);

                apr.SetSharedMaterials(new Material[] { subassets.pointsMaterial });
                apr.motionVectorMaterial = subassets.pointsMotionVectorMaterial;
            }

            foreach (var child in node.Children)
            {
                CollectSubAssets(subassets, child);
            }
        }
        void GenerateSubAssets(Subassets subassets, AlembicTreeNode root, AlembicStreamDescriptor streamDescr)
        {
            if (streamDescr.duration > 0)
            {
                // AnimationClip for time
                {
                    var frames = new Keyframe[2];
                    frames[0].value      = 0.0f;
                    frames[0].time       = 0.0f;
                    frames[0].outTangent = 1.0f;
                    frames[1].value      = (float)streamDescr.duration;
                    frames[1].time       = (float)streamDescr.duration;
                    frames[1].inTangent  = 1.0f;

                    var curve = new AnimationCurve(frames);
                    AnimationUtility.SetKeyLeftTangentMode(curve, 0, AnimationUtility.TangentMode.Linear);
                    AnimationUtility.SetKeyRightTangentMode(curve, 1, AnimationUtility.TangentMode.Linear);

                    var clip = new AnimationClip();
                    clip.SetCurve("", typeof(AlembicStreamPlayer), "currentTime", curve);
                    clip.name      = root.gameObject.name + "_Time";
                    clip.hideFlags = HideFlags.NotEditable;

                    subassets.Add("Default Animation", clip);
                }

                // AnimationClip for frame events
                {
                    var abc = root.stream.abcContext;
                    var n   = abc.timeSamplingCount;
                    for (int i = 1; i < n; ++i)
                    {
                        var clip = new AnimationClip();
                        if (AddFrameEvents(clip, abc.GetTimeSampling(i)))
                        {
                            var name = root.gameObject.name + "_Frames";
                            if (n > 2)
                            {
                                name += i.ToString();
                            }
                            clip.name = name;
                            subassets.Add(clip.name, clip);
                        }
                    }
                }
            }
            varyingTopologyMeshNames = new List <string>();
            splittingMeshNames       = new List <string>();

            CollectSubAssets(subassets, root);

            streamDescr.HasVaryingTopology = VaryingTopologyMeshNames.Count > 0;
        }
        void CollectSubAssets(Subassets subassets, AlembicTreeNode node)
        {
            int submeshCount = 0;
            var meshFilter   = node.gameObject.GetComponent <MeshFilter>();

            if (meshFilter != null)
            {
                var m = meshFilter.sharedMesh;
                submeshCount = m.subMeshCount;
                m.name       = node.gameObject.name;
                subassets.Add(node.abcObject.abcObject.fullname, m);
            }

            var renderer = node.gameObject.GetComponent <MeshRenderer>();

            if (renderer != null)
            {
                var mats = new Material[submeshCount];
                for (int i = 0; i < submeshCount; ++i)
                {
                    mats[i] = subassets.defaultMaterial;
                }
                renderer.sharedMaterials = mats;
            }

            var apr = node.gameObject.GetComponent <AlembicPointsRenderer>();

            if (apr != null)
            {
                var cubeGO = GameObject.CreatePrimitive(PrimitiveType.Cube);
                apr.InstancedMesh = cubeGO.GetComponent <MeshFilter>().sharedMesh;
                DestroyImmediate(cubeGO);

                apr.Materials = new List <Material> {
                    subassets.pointsMaterial
                };
                apr.MotionVectorMaterial = subassets.pointsMotionVectorMaterial;
            }

            foreach (var child in node.Children)
            {
                CollectSubAssets(subassets, child);
            }
        }