private static List<HalfVector2> GetUVsForModel(MyExportModel renderModel, int modelVerticesCount)
 {
     return renderModel.GetTexCoords().ToList();
 }
        private static List<MyExportModel.Material> CreateMaterialsForModel(Dictionary<string, MyExportModel.Material> materials, Vector3 colorMaskHSV, MyExportModel renderModel)
        {
            List<MyExportModel.Material> newModelMaterials = new List<MyExportModel.Material>();
            List<MyExportModel.Material> modelMaterials = renderModel.GetMaterials();
            foreach (var material in modelMaterials)
            {
                string diffuseTextureName = GetDiffuseTextureName(material.DiffuseTexture);
                bool materialFound = false;
                foreach (var savedMaterial in materials)
                {
                    if (savedMaterial.Value.DiffuseTexture.Equals(diffuseTextureName, StringComparison.OrdinalIgnoreCase) &&
                        Math.Abs(savedMaterial.Value.ColorMaskHSV.X - colorMaskHSV.X) < 0.01f &&
                        Math.Abs(savedMaterial.Value.ColorMaskHSV.Y - colorMaskHSV.Y) < 0.01f &&
                        Math.Abs(savedMaterial.Value.ColorMaskHSV.Z - colorMaskHSV.Z) < 0.01f)
                    {
                        MyExportModel.Material newMaterial = material;
                        newMaterial.DiffuseTexture = diffuseTextureName;
                        //each time new material is created new name for this material is assgined e.g. Material_x
                        //but model materials have they original name so we need to swap material name with created one
                        newMaterial.Name = savedMaterial.Value.Name;
                        newModelMaterials.Add(newMaterial);
                        materialFound = true;
                        break;
                    }
                }
                if (false == materialFound)
                {
                    materialID++;

                    MyExportModel.Material newMaterial = material;
                    newMaterial.Name = "material_" + materialID.ToString();                 
                    newMaterial.ColorMaskHSV = colorMaskHSV;
                    newMaterial.DiffuseTexture = diffuseTextureName;
                    newMaterial.NewDiffuseTexture = newMaterial.Name + ".png";                   
                    newModelMaterials.Add(newMaterial);
                    materials.Add(newMaterial.Name, newMaterial);
                }
            }
            return newModelMaterials;
        }
        private static void ExtractModelDataForObj(
            MyModel model,
            Matrix matrix,
            List<Vector3> vertices,
            List<TriangleWithMaterial> triangles,
            List<Vector2> uvs,
            ref Vector2 offsetUV,
            Dictionary<string, MyExportModel.Material> materials,
            ref int currVerticesCount,
            Vector3 colorMaskHSV)
        {
            if (false == model.HasUV)
            {
                model.LoadUV = true;
                model.UnloadData();
                model.LoadData();
            }

            MyExportModel renderModel = new MyExportModel(model);

            int modelVerticesCount = renderModel.GetVerticesCount();

            List<HalfVector2> modelUVs = GetUVsForModel(renderModel, modelVerticesCount);
            Debug.Assert(modelUVs.Count == modelVerticesCount, "wrong UVs for model");
            if (modelUVs.Count != modelVerticesCount)
            {
                return;
            }

            //we need new material for every HSV and texture combination, therefore we need to create new materials for each model
            List<MyExportModel.Material> newModelMaterials = CreateMaterialsForModel(materials, colorMaskHSV, renderModel);

            for (int i = 0; i < modelVerticesCount; ++i)
            {
                vertices.Add(Vector3.Transform(model.GetVertex(i), matrix));
                Vector2 localUV = modelUVs[i].ToVector2()/model.PatternScale + offsetUV;
                uvs.Add(new Vector2(localUV.X, -localUV.Y));
            }

            for (int i = 0; i < renderModel.GetTrianglesCount(); ++i)
            {
                int matID = -1;
                for (int j = 0; j < newModelMaterials.Count; ++j)
                {
                    if (i <= newModelMaterials[j].LastTri)
                    {
                        matID = j;
                        break;
                    }
                }
                Debug.Assert(matID != -1, "Triangle with no material");

                var t = renderModel.GetTriangle(i);
                string materialName = "EmptyMaterial";
                if (matID != -1)
                {
                    materialName = newModelMaterials[matID].Name;
                }
                triangles.Add(new TriangleWithMaterial()
                {
                    triangle = new MyTriangleVertexIndices(t.I0 + 1 + currVerticesCount, t.I1 + 1 + currVerticesCount, t.I2 + 1 + currVerticesCount),
                    material = materialName,
                });
            }
            currVerticesCount += modelVerticesCount;
        }