protected VertexComponents BuildVertexComponents(FaceTriplets triplets, Point3[] positions, Point3[] normals, Point3[] tex1, Point3[] tex2 )
        {
            int vertexcount = triplets.uniqueTriplets.Count;

            var vc = new VertexComponents(vertexcount);

            for (int i = 0; i < vertexcount; i++)
            {
                Triplet triplet = triplets.uniqueTriplets[i];

                vc.vertices[i] = ToVector3(positions[triplet.v]);
                vc.normals[i] = ToVector3(normals[triplet.n]);
                vc.uvs[i] = ToVector2(tex1[triplet.t]);
                vc.uvs2[i] = ToVector2(tex2[triplet.y]);
            }

            return vc;

        }
 protected IEnumerable<FaceIndicesGroup> DereferenceFaceTripletGroups(IEnumerable<FaceTripletGroup> facetripletgroups, FaceTriplets triplets)
 {
     foreach (var fg in facetripletgroups)
     {
         yield return DereferenceFaceTriplets(fg, triplets);
     }
 }
        protected FaceIndicesGroup DereferenceFaceTriplets(FaceTripletGroup faces, FaceTriplets triplets)
        {
            List<int> indices = new List<int>();

            foreach (var f in faces.Triplets)
            {
                indices.Add(triplets.GetTripletIndex(f));
            }

            return new FaceIndicesGroup { MaterialId = faces.MaterialId, FaceIndices = indices.ToArray() };
        }
        /// <summary>
        /// Processes update with heterogenous vertex component arrays into a single set of homogenous arrays based on face data, and calculates tangents
        /// </summary>
        /// <param name="Update"></param>
        /// <returns></returns>
        protected UnityStyleMesh ConvertMeshToUnityStyle(GeometryNode Update)
        {
            /* In Max, and the portable mesh, each triangle is made of a number of faces superimposed on eachother. Those faces contain indices into different vertex arrays.
             * The vertex arrays contain positions, texture coords, normals, etc. This function flattens these, so each face is made up of 3 sets of 4 indices. One set for
             * each corner, and the sets containing the indices into the various vertex arrays referenced by the original 'sub'-faces. */

            var positionChannel = ChannelExtensions.GetPositionChannel(Update.Channels);
            var normalChannel = ChannelExtensions.GetNormalsChannel(Update.Channels);
            var texture_tChannel = ChannelExtensions.GetTextureChannel(Update.Channels, VertexChannelType.Texture1);
            var texture_yChannel = ChannelExtensions.GetTextureChannel(Update.Channels, VertexChannelType.Texture2);

            var faceTripletGroups = CreateFaceTripletGroups(Update.FaceGroups,
                positionChannel,
                normalChannel,
                texture_tChannel,
                texture_yChannel);


            /* For each face triple (set of 4 indices), dereference it so they all become indices into a single master list of triplets. This master list can then
             * be used to create a vertex array. */

            var triplets = new FaceTriplets();

            var faceindexgroups = DereferenceFaceTripletGroups(faceTripletGroups, triplets).ToList();


            /* Build the vertex component arrays based on the master triplet array created above */

            var vertexcomponents = BuildVertexComponents(triplets, positionChannel.m_vertices, normalChannel.m_vertices, texture_tChannel.m_vertices, texture_yChannel.m_vertices);


            return new UnityStyleMesh { components = vertexcomponents, face_groups = faceindexgroups };
        }