Beispiel #1
0
        private static ToolResult CopyUsedTexturesObj(string objFile, string outputDirectory, string textureDirectory)
        {
            bool    success = false;
            string  message = "";
            ObjData objData = ObjParser.TryParseObj(objFile);

            if (objData != null)
            {
                objData.UpdateMtlData();
                MtlData mtlData = objData.Mtl;

                if (mtlData != null)
                {
                    success = ObjModifier.CopyUsedTextures(mtlData, outputDirectory, textureDirectory);
                    message = MessageBoxConstants.GetMessageExecutionGeneric(success);
                }
                else
                {
                    message = MessageBoxConstants.MessageErrorCopyTextures + MessageBoxConstants.MessageMtlNotFound;
                }
            }
            else
            {
                message = MessageBoxConstants.GetMessageExecutionErrorParse(objFile);
            }
            return(new ToolResult(message, success));
        }
        private void LineReaded(string[] t)
        {
            switch (t[0])
            {
            case "mtllib":  LoadMtlLib(t[1]);                   break;

            case "v":       AddVector3(Positions, t);           break;

            case "vn":      AddVector3(Normals, t);           break;

            case "vt":      AddVector3(TexCoords, t);           break;

            case "o":       CurrentName = t[1];                 break;

            case "g":       CurrentName = t[1];                 break;

            case "usemtl":  NewMesh("").Material = MtlData == null ? null : MtlData.Get(t[1]);    break; // usemtl mat0

            case "s":       NewSubMesh(0).Name = CurrentName;  break;                                    // s 1

            case "f":       GetCurrentSubMesh().AddFace(t);     break;                                   // f 1/1/1 2/2/2 3/3/3

            //Account for blender line output
            case "l":       break;

            default:    throw new FormatException();
            }
        }
Beispiel #3
0
        /// <summary>
        /// Delete every unused material the obj file
        /// </summary>
        /// <param name="objData">Data parsed from the obj file</param>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        public static bool DeleteUnusedMaterials(ObjData objData, MtlData mtlData)
        {
            if (mtlData == null)
            {
                return(false);
            }

            // Dictionary that associate every material to a list of groups
            Dictionary <string, List <int> > dictMaterialGroups = ObjUtils.GetDictMaterialGroups(objData);

            // Dictionary that associate every material of the mtl file to their index
            Dictionary <string, int> dictMaterialIndex = MtlUtils.GetDictMaterialIndex(mtlData);

            List <MaterialMtl> newMaterialsList = new List <MaterialMtl>();

            foreach (KeyValuePair <string, List <int> > keyValue in dictMaterialGroups)
            {
                if (dictMaterialIndex.TryGetValue(keyValue.Key, out int index)) // We get the index of the material
                {
                    MaterialMtl materialMtl = mtlData.MaterialsList[index];
                    newMaterialsList.Add(materialMtl);
                }
            }

            // Every material that wasnt used in a group was not added to the list
            mtlData.MaterialsList = newMaterialsList;
            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Rename every material from the obj and mtl to make them unique after the merge
        /// </summary>
        /// <param name="objData"></param>
        /// <param name="mtlData"></param>
        /// <param name="indexMaterial"></param>
        private static void SetUniqueMaterialsNames(ObjData objData, MtlData mtlData, IntWrapper indexMaterial)
        {
            // Dictionary that associate every material to a list of groups
            Dictionary <string, List <int> > dictMaterialGroups = ObjUtils.GetDictMaterialGroups(objData);

            if (mtlData == null) // Need to rename the Materials in obj only
            {
                foreach (KeyValuePair <string, List <int> > keyValue in dictMaterialGroups)
                {
                    SetUniqueMaterialsName(objData, keyValue.Value, indexMaterial);
                    indexMaterial.Value++;
                }
            }
            else // Need to rename the Materials in both obj and mtl
            {
                // Dictionary that associate every material of the mtl file to their index
                Dictionary <string, int> dictMaterialIndex = MtlUtils.GetDictMaterialIndex(mtlData);

                foreach (KeyValuePair <string, List <int> > keyValue in dictMaterialGroups)
                {
                    SetUniqueMaterialsName(objData, keyValue.Value, indexMaterial);

                    if (dictMaterialIndex.TryGetValue(keyValue.Key, out int index)) // We get the index of the material
                    {
                        MaterialMtl materialMtl = mtlData.MaterialsList[index];
                        if (materialMtl.NewMtl != null)
                        {
                            materialMtl.NewMtl = GenericUtils.MergeIndexStr(indexMaterial.Value, materialMtl.NewMtl);
                        }
                    }
                    indexMaterial.Value++;
                }
            }
        }
Beispiel #5
0
        private static ToolResult ConvertObjToSmd(string objFile, string smdOutput, bool useTextureName)
        {
            bool    success = false;
            string  message = "";
            ObjData objData = ObjParser.TryParseObj(objFile);

            if (objData != null)
            {
                objData.UpdateMtlData();
                MtlData mtlData = objData.Mtl;

                if (mtlData == null)
                {
                    // No MTL means the SMD will use a default material name for all objects
                    useTextureName = false;
                }
                success = SmdExporter.WriteSmd(objData, mtlData, smdOutput, useTextureName);
                message = MessageBoxConstants.GetMessageExecutionCreation(success, smdOutput);
            }
            else
            {
                message = MessageBoxConstants.GetMessageExecutionErrorParse(objFile);
            }
            return(new ToolResult(message, success));
        }
Beispiel #6
0
        private static ToolResult DeleteUnusedMaterialsObj(string objFile, string objOutput)
        {
            bool    success = false;
            string  message = "";
            ObjData objData = ObjParser.TryParseObj(objFile);

            if (objData != null)
            {
                objData.UpdateMtlData();
                MtlData mtlData = objData.Mtl;
                if (mtlData != null)
                {
                    ObjModifier.DeleteUnusedMaterials(objData, mtlData);
                    success = ObjExporter.WriteObj(objData, mtlData, objOutput, makeMtl: true, useExistingMtl: true);
                    message = MessageBoxConstants.GetMessageExecutionCreation(success, objOutput);
                }
                else
                {
                    message = MessageBoxConstants.MessageErrorDeleteUnusedMaterials +
                              MessageBoxConstants.MessageMtlNotFound;
                }
            }
            else
            {
                message = MessageBoxConstants.GetMessageExecutionErrorParse(objFile);
            }
            return(new ToolResult(message, success));
        }
Beispiel #7
0
 /// <summary>
 /// Try to delete all groups that use textures from a given list (compare the textures)
 /// </summary>
 /// <param name="objData">Data parsed from the obj file</param>
 /// <param name="mtlData">Data parsed from the mtl file</param>
 /// <param name="listFileName">List of textures that should be matched</param>
 /// <returns>true if successful, false if error</returns>
 public static bool TryDeleteMatchingGroups(ObjData objData, MtlData mtlData, List <string> listFileName)
 {
     try
     {
         return(DeleteMatchingGroups(objData, mtlData, listFileName));
     }
     catch
     {
         return(false);
     }
 }
Beispiel #8
0
 public ObjMaterial(ShaderProgram program, MtlData aMtlData)
 {
     Name                = aMtlData.Name;
     Transparency        = (float)aMtlData.d;
     Ambient             = aMtlData.Ka;
     Diffuse             = aMtlData.Kd;
     Specular            = aMtlData.Ks;
     SpecularCoefficient = (float)aMtlData.Ns;
     Illumination        = (IlluminationMode)aMtlData.illum;
     Program             = program;
 }
Beispiel #9
0
 /// <summary>
 /// Iterate through the mtl to update every texture associated to each material in the obj
 /// </summary>
 /// <param name="objData">Data parsed from the obj file</param>
 /// <param name="mtlData">Data parsed from the mtl file</param>
 public static void UpdateUsedTexture(ObjData objData, MtlData mtlData)
 {
     if (mtlData != null)
     {
         Dictionary <string, string> dictMaterialTexture = MtlUtils.GetDictMaterialTexture(mtlData);
         foreach (ObjectObj objectObj in objData.ObjectsList)
         {
             if (objectObj.MaterialName != null)
             {
                 objectObj.TextureName = MtlUtils.GetTextureFromMaterial(dictMaterialTexture, objectObj.MaterialName);
             }
         }
     }
 }
Beispiel #10
0
        /// <summary>
        /// Return a Hash List of all Textures used in the mtl
        /// </summary>
        /// <param name="mtlData"></param>
        /// <returns></returns>
        public static HashSet <string> GetListTextures(MtlData mtlData)
        {
            HashSet <string> textureList = new HashSet <string>();

            foreach (MaterialMtl materialMtl in mtlData.MaterialsList)
            {
                if (materialMtl.NewMtl != null && materialMtl.MapKd != null)
                {
                    textureList.Add(materialMtl.MapKd);
                }
            }

            return(textureList);
        }
Beispiel #11
0
        /// <summary>
        /// Return a dictionary with each Material associated to a Texture
        /// </summary>
        /// <param name="mtlData"></param>
        /// <returns></returns>
        public static Dictionary <string, string> GetDictMaterialTexture(MtlData mtlData)
        {
            Dictionary <string, string> dict = new Dictionary <string, string>();

            foreach (MaterialMtl materialMtl in mtlData.MaterialsList)
            {
                if (materialMtl.NewMtl != null && materialMtl.MapKd != null)
                {
                    dict.Add(materialMtl.NewMtl, materialMtl.MapKd);
                }
            }

            return(dict);
        }
Beispiel #12
0
        /// <summary>
        /// Merge together every materials in the array
        /// </summary>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        /// <param name="textureName">Path to the texture file</param>
        /// <param name="materials">List of materials index</param>
        /// <returns></returns>
        private static MaterialMtl MergeMaterials(MtlData mtlData, string textureName, List <int> materials)
        {
            if (materials.Count >= 1) // Should always be the case
            {
                string relativeTexture = System.IO.Path.GetFileName(textureName);

                MaterialMtl materialMtl = new MaterialMtl(mtlData.MaterialsList[materials[0]])
                {
                    NewMtl = relativeTexture // The material name will be the same as the texture file
                };
                return(materialMtl);
            }
            return(null);
        }
Beispiel #13
0
        /// <summary>
        /// Sort materials alphabetically
        /// </summary>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        public static bool SortMaterials(MtlData mtlData)
        {
            if (mtlData == null)
            {
                return(false);
            }

            foreach (MaterialMtl materialMtl in mtlData.MaterialsList)
            {
                if (materialMtl.NewMtl == null) // if a NewMtl is null, sorting would throw an exception
                {
                    return(false);
                }
            }

            mtlData.MaterialsList.Sort((p, q) => p.NewMtl.CompareTo((q.NewMtl)));
            return(true);
        }
Beispiel #14
0
        /// <summary>
        /// Return a dictionary with each Material associated to their indexes in the materials list
        /// </summary>
        /// <param name="mtlData"></param>
        /// <returns></returns>
        public static Dictionary <string, int> GetDictMaterialIndex(MtlData mtlData)
        {
            var dict = new Dictionary <string, int>();

            int i = 0;

            foreach (MaterialMtl materialMtl in mtlData.MaterialsList)
            {
                if (materialMtl.NewMtl != null)
                {
                    if (!dict.ContainsKey(materialMtl.NewMtl)) // The material wasn't added yet
                    {
                        dict.Add(materialMtl.NewMtl, i);
                    }
                }
                i++;
            }
            return(dict);
        }
Beispiel #15
0
        /// <summary>
        /// Parse the given mtl file
        /// </summary>
        /// <param name="file">File to parse</param>
        /// <returns></returns>
        public static MtlData ParseMtl(string file)
        {
            string[] lines = GenericUtils.RemoveBlankSpaces(FileUtilsShared.ReadFile(file)); // Read the file and remove blankspaces
            if (lines != null)
            {
                // Store all the other data to parse
                List <Tuple <string, string> > listKeysValues = GetListKeysValues(lines);

                MtlData mtlData = new MtlData(file);

                lines = null; // To let the garbage collector free the file from memory
                int i      = 0;
                int length = listKeysValues.Count;

                while (i < length)
                {
                    Tuple <string, string> keyValue = listKeysValues[i];
                    if (keyValue != null) // Never null unless error or final line
                    {
                        if (MtlUtils.IsNewMtl(keyValue.Item1))
                        {
                            int materialStart = i;
                            int materialEnd   = GetIndexEnd(listKeysValues, length, materialStart);

                            if (materialEnd != -1)
                            {
                                mtlData.MaterialsList.Add(MaterialData(listKeysValues, materialStart, materialEnd));
                                i = materialEnd; // Set to next material
                                continue;
                            }
                        }
                    }
                    i++;
                }
                return(mtlData);
            }
            return(null);
        }
Beispiel #16
0
        /// <summary>
        /// Create the mtl file with the given data
        /// </summary>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        /// <param name="mtlFilename">Output path</param>
        /// <returns></returns>
        public static bool WriteMtl(MtlData mtlData, string mtlFilename)
        {
            try
            {
                using (StreamWriter mtl = new StreamWriter(mtlFilename))
                {
                    mtl.WriteLine(GenericUtils.GetCreditsFile());

                    // newmtl, Ns, Ka, Kd, Ks, Ni, d, illum, map_Kd, map_Ka, map_Ks, map_d
                    foreach (MaterialMtl material in mtlData.MaterialsList)
                    {
                        mtl.WriteLine(MtlUtils.GetNewNewMtl(material.NewMtl));
                        mtl.WriteLine(MtlUtils.GetNewNs(material.Ns));

                        if (material.Ka != null)
                        {
                            mtl.WriteLine(MtlUtils.GetNewKa(material.Ka.ToString()));
                        }
                        else
                        {
                            mtl.WriteLine(MtlUtils.GetNewKa());
                        }

                        if (material.Kd != null)
                        {
                            mtl.WriteLine(MtlUtils.GetNewKd(material.Kd.ToString()));
                        }
                        else
                        {
                            mtl.WriteLine(MtlUtils.GetNewKd());
                        }

                        if (material.Ks != null)
                        {
                            mtl.WriteLine(MtlUtils.GetNewKs(material.Ks.ToString()));
                        }
                        else
                        {
                            mtl.WriteLine(MtlUtils.GetNewKs());
                        }

                        if (material.Ke != null)
                        {
                            mtl.WriteLine(MtlUtils.GetNewKe(material.Ke.ToString()));
                        }
                        else
                        {
                            mtl.WriteLine(MtlUtils.GetNewKe());
                        }

                        mtl.WriteLine(MtlUtils.GetNewNi(material.Ni));
                        mtl.WriteLine(MtlUtils.GetNewD(material.D));
                        mtl.WriteLine(MtlUtils.GetNewIllum(material.Illum));

                        if (material.MapKd != null)
                        {
                            mtl.WriteLine(MtlUtils.GetNewMapKd(material.MapKd));
                        }
                        if (material.MapKa != null)
                        {
                            mtl.WriteLine(MtlUtils.GetNewMapKa(material.MapKa));
                        }
                        if (material.MapKs != null)
                        {
                            mtl.WriteLine(MtlUtils.GetNewMapKs(material.MapKs));
                        }
                        if (material.MapD != null)
                        {
                            mtl.WriteLine(MtlUtils.GetNewMapD(material.MapD));
                        }

                        mtl.WriteLine(); // Empty line
                    }
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
Beispiel #17
0
        /// <summary>
        /// Create the obj and mtl files with the given data
        /// </summary>
        /// <param name="objData">Data parsed from the obj file</param>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        /// <param name="objFilename">Output path</param>
        /// <param name="makeMtl">Create a mtl file</param>
        /// <param name="useExistingMtl">Use the mtlData to create the mtl file</param>
        /// <returns></returns>
        public static bool WriteObj(ObjData objData, MtlData mtlData, string objFilename, bool makeMtl, bool useExistingMtl)
        {
            // objFilename has the .obj extension
            string directory   = System.IO.Path.GetDirectoryName(objFilename);
            string noExtension = System.IO.Path.GetFileNameWithoutExtension(objFilename);
            string mtlRelative = string.Format("{0}.mtl", noExtension);
            string mtlFilename = System.IO.Path.Combine(directory, mtlRelative);

            List <string> mtlLines = new List <string>(); // To store the lines to append to the mtl file

            try
            {
                using (StreamWriter obj = new StreamWriter(objFilename))
                {
                    // mtllib, o, v, vt, g, usemtl, s, f

                    obj.WriteLine(GenericUtils.GetCreditsFile());
                    if (makeMtl)
                    {
                        obj.WriteLine(ObjUtils.GetNewMtlLib(mtlRelative));
                    }

                    LocalIndexesObj indexesObj = new LocalIndexesObj();

                    foreach (ObjectObj objectObj in objData.ObjectsList)
                    {
                        if (objectObj.ObjectName != null)
                        {
                            obj.WriteLine(ObjUtils.GetNewObject(objectObj.ObjectName)); // o
                        }
                        foreach (Point p in objectObj.VerticesList)
                        {
                            obj.WriteLine(ObjUtils.GetNewCoord(p.ToString())); // v
                        }
                        foreach (UVCoordinates uv in objectObj.UVsList)
                        {
                            obj.WriteLine(ObjUtils.GetNewTexCoord(uv.ToString())); // vt
                        }
                        foreach (Vector v in objectObj.NormalsList)
                        {
                            obj.WriteLine(ObjUtils.GetNewVertNormal(v.ToString())); // vn
                        }
                        if (objectObj.GroupName != null)
                        {
                            obj.WriteLine(ObjUtils.GetNewGroup(objectObj.GroupName)); // g
                        }
                        if (objectObj.MaterialName != null)
                        {
                            obj.WriteLine(ObjUtils.GetNewUseMtl(objectObj.MaterialName)); // usemtl
                            // Store lines in the mtl array to append to the file later
                            mtlLines.Add(MtlUtils.GetMtlData(objectObj.MaterialName, objectObj.TextureName));
                        }

                        if (objectObj.Smooth == -1)
                        {
                            obj.WriteLine(ObjUtils.GetNewSmoothGroup()); // s
                        }
                        else
                        {
                            obj.WriteLine(ObjUtils.GetNewSmoothGroup(objectObj.Smooth)); // s
                        }
                        foreach (VertIndexesObj vertIndexes in objectObj.VertIndexesList)
                        {
                            obj.WriteLine(ObjUtils.GetNewF(GetDataF(vertIndexes, indexesObj))); // f
                        }
                        indexesObj.vIndex  += objectObj.VerticesList.Count;
                        indexesObj.vtIndex += objectObj.UVsList.Count;
                        indexesObj.vnIndex += objectObj.NormalsList.Count;
                    }
                }
            }
            catch
            {
                return(false);
            }

            if (makeMtl)                               // If we dont delete materials
            {
                if (useExistingMtl && mtlData != null) // Use the parsed mtl
                {
                    return(MtlExporter.WriteMtl(mtlData, mtlFilename));
                }
                else // Create a mtl from the data obtained in the obj
                {
                    return(MtlExporter.WriteMtl(mtlLines, mtlFilename));
                }
            }

            return(true);
        }
Beispiel #18
0
        /// <summary>
        /// Return the join of the TextureMaterial and MaterialGroup dictionaries
        /// </summary>
        /// <param name="objData"></param>
        /// <returns></returns>
        public static Dictionary <string, List <int> > GetDictTextureGroups(ObjData objData, MtlData mtlData,
                                                                            Dictionary <string, List <int> > dictTextureMaterials, Dictionary <string, List <int> > dictMaterialGroups)
        {
            Dictionary <string, List <int> > dictTextureGroups = new Dictionary <string, List <int> >();

            foreach (KeyValuePair <string, List <int> > textureMaterial in dictTextureMaterials)
            {
                List <int> groupIdList = new List <int>();
                foreach (int materialId in textureMaterial.Value)
                {
                    string materialName = mtlData.MaterialsList[materialId].NewMtl;

                    if (dictMaterialGroups.TryGetValue(materialName, out List <int> groups))
                    {
                        if (groups != null)
                        {
                            foreach (int groupId in groups)
                            {
                                groupIdList.Add(groupId);
                            }
                        }
                    }
                }
                dictTextureGroups.Add(textureMaterial.Key, groupIdList); // The texture is associated a list of group
            }
            return(dictTextureGroups);
        }
Beispiel #19
0
        /// <summary>
        /// Create the smd file with the given data
        /// </summary>
        /// <param name="objData">Data parsed from the obj file</param>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        /// <param name="smdFilename">Output path</param>
        /// <returns></returns>
        public static bool WriteSmd(ObjData objData, MtlData mtlData, string smdFilename, bool useTextureName)
        {
            if (useTextureName)
            {
                ObjModifier.UpdateUsedTexture(objData, mtlData);
            }
            try
            {
                using (StreamWriter smd = new StreamWriter(smdFilename))
                {
                    // version 1
                    smd.WriteLine(SmdUtils.GetNewHeader());

                    // nodes
                    smd.WriteLine(SmdUtils.GetNewNodes());
                    smd.WriteLine(SmdUtils.GetNewBone());
                    smd.WriteLine(SmdUtils.GetNewEnd());

                    // skeleton
                    smd.WriteLine(SmdUtils.GetNewSkeleton());
                    smd.WriteLine(SmdUtils.GetNewTime());
                    smd.WriteLine(SmdUtils.GetNewPosition());
                    smd.WriteLine(SmdUtils.GetNewEnd());

                    // triangles
                    smd.WriteLine(SmdUtils.GetNewTriangles());
                    foreach (ObjectObj objectObj in objData.ObjectsList)
                    {
                        string smdMaterial = GetSmdMaterial(objectObj.MaterialName, objectObj.TextureName, useTextureName);

                        int coordLength  = objectObj.VerticesList.Count;
                        int uvLength     = objectObj.UVsList.Count;
                        int normalLength = objectObj.NormalsList.Count;

                        foreach (VertIndexesObj vertIndexes in objectObj.VertIndexesList)
                        {
                            smd.WriteLine(smdMaterial);
                            foreach (VertIndexObj vertIndex in vertIndexes.VertIndexList)
                            {
                                string coordStr  = DefaultCoord;
                                string uvStr     = DefaultUV;
                                string normalStr = DefaultCoord;


                                if (vertIndex.V != null)
                                {
                                    if (vertIndex.V < coordLength) // Should always be the case
                                    {
                                        // Source Engine use 'z' for the up-down axis
                                        coordStr = objectObj.VerticesList[(int)vertIndex.V].ToSmd();
                                    }
                                }

                                if (vertIndex.Vt != null)
                                {
                                    if (vertIndex.Vt < uvLength) // Should always be the case
                                    {
                                        uvStr = objectObj.UVsList[(int)vertIndex.Vt].ToString();
                                    }
                                }

                                if (vertIndex.Vn != null)
                                {
                                    if (vertIndex.Vn < normalLength) // Should always be the case
                                    {
                                        // Source Engine use 'z' for the up-down axis
                                        normalStr = objectObj.NormalsList[(int)vertIndex.Vn].ToSmd();
                                    }
                                }

                                smd.WriteLine(SmdUtils.GetNewTriangle(0, coordStr, normalStr, uvStr));
                            }
                        }
                    }
                    smd.WriteLine(SmdUtils.GetNewEnd());
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
Beispiel #20
0
        /// <summary>
        /// Return a tuple with a dictionary of each Texture associated to the indexes of their Materials
        /// and a list of Materials without any texture
        /// </summary>
        /// <param name="mtlData"></param>
        /// <returns></returns>
        public static Tuple <Dictionary <string, List <int> >, List <int> > GetTupleDictTextureMaterials(MtlData mtlData)
        {
            Dictionary <string, List <int> > dict = new Dictionary <string, List <int> >();
            List <int> untexturedMaterials        = new List <int>();

            int i = 0;

            foreach (MaterialMtl materialMtl in mtlData.MaterialsList)
            {
                if (materialMtl.NewMtl != null)
                {
                    if (materialMtl.MapKd != null)
                    {
                        if (dict.TryGetValue(materialMtl.MapKd, out List <int> materials))
                        {
                            materials.Add(i); // If the keyvalue already exists, we add the new index
                        }
                        else
                        {
                            dict.Add(materialMtl.MapKd, new List <int>()
                            {
                                i
                            });                                                 // Otherwise, we create the new keyvalue
                        }
                    }
                    else // Material without any texture
                    {
                        untexturedMaterials.Add(i);
                    }
                }
                i++;
            }
            return(new Tuple <Dictionary <string, List <int> >, List <int> >(dict, untexturedMaterials));
        }
Beispiel #21
0
        private static ToolResult ModifyObj(string objFile, string objOutput, ObjOptions objOptions, Dictionary <string, string> inputs)
        {
            bool          success = false;
            bool          warn    = false;
            StringBuilder sb      = new StringBuilder();
            ObjData       objData = ObjParser.TryParseObj(objFile);

            if (objData != null)
            {
                objData.UpdateMtlData();
                MtlData mtlData = objData.Mtl;

                if (objOptions.HasFlag(ObjOptions.BlackList))
                {
                    // Delete Blacklisted Objects first
                    if (mtlData != null)
                    {
                        if (!ObjModifier.TryDeleteMatchingGroups(objData, mtlData, texturesList))
                        {
                            warn = true;
                            sb.AppendLine(MessageBoxConstants.MessageErrorDeleteBlackList + MessageBoxConstants.MessageErrorExecution);
                        }
                    }
                    else
                    {
                        warn = true;
                        sb.AppendLine(MessageBoxConstants.MessageErrorDeleteBlackList + MessageBoxConstants.MessageMtlNotFound);
                    }
                }

                ObjModifier.CalculateNormal(objData);

                if (objOptions.HasFlag(ObjOptions.UniformScale))
                {
                    if (inputs.TryGetValue(DictConstants.ScaleValue, out string scaleStr))
                    {
                        if (Double.TryParse(scaleStr, out double scaleValue))
                        {
                            ObjModifier.UniformScale(objData, scaleValue); // Scale Model
                        }
                        else
                        {
                            warn = true;
                            sb.AppendLine(MessageBoxConstants.MessageErrorScale + MessageBoxConstants.MessageInvalidScaleValue);
                        }
                    }
                }

                if (objOptions.HasFlag(ObjOptions.NonUniformScale))
                {
                    bool   isScaleValueX = false;
                    bool   isScaleValueY = false;
                    bool   isScaleValueZ = false;
                    double scaleValueX   = 0.0;
                    double scaleValueY   = 0.0;
                    double scaleValueZ   = 0.0;
                    if (inputs.TryGetValue(DictConstants.ScaleValueX, out string scaleStr))
                    {
                        isScaleValueX = Double.TryParse(scaleStr, out scaleValueX);
                    }
                    if (inputs.TryGetValue(DictConstants.ScaleValueY, out scaleStr))
                    {
                        isScaleValueY = Double.TryParse(scaleStr, out scaleValueY);
                    }
                    if (inputs.TryGetValue(DictConstants.ScaleValueZ, out scaleStr))
                    {
                        isScaleValueZ = Double.TryParse(scaleStr, out scaleValueZ);
                    }
                    if (isScaleValueX && isScaleValueY && isScaleValueZ)
                    {
                        // Scale Model
                        ObjModifier.NonUniformScale(objData, scaleValueX, scaleValueY, scaleValueZ);
                    }
                    else
                    {
                        warn = true;
                        sb.AppendLine(MessageBoxConstants.MessageErrorScale + MessageBoxConstants.MessageInvalidScaleValues);
                    }
                }

                if (objOptions.HasFlag(ObjOptions.Rotate))
                {
                    bool   isRotateValueX = false;
                    bool   isRotateValueY = false;
                    bool   isRotateValueZ = false;
                    double rotateValueX   = 0.0;
                    double rotateValueY   = 0.0;
                    double rotateValueZ   = 0.0;
                    if (inputs.TryGetValue(DictConstants.RotateValueX, out string rotationStr))
                    {
                        isRotateValueX = Double.TryParse(rotationStr, out rotateValueX);
                    }
                    if (inputs.TryGetValue(DictConstants.RotateValueY, out rotationStr))
                    {
                        isRotateValueY = Double.TryParse(rotationStr, out rotateValueY);
                    }
                    if (inputs.TryGetValue(DictConstants.RotateValueZ, out rotationStr))
                    {
                        isRotateValueZ = Double.TryParse(rotationStr, out rotateValueZ);
                    }
                    if (isRotateValueX && isRotateValueY && isRotateValueZ)
                    {
                        // Rotate Model
                        ObjModifier.RotateModel(objData, rotateValueX, rotateValueY, rotateValueZ);
                    }
                    else
                    {
                        warn = true;
                        sb.AppendLine(MessageBoxConstants.MessageErrorRotate + MessageBoxConstants.MessageInvalidRotateValues);
                    }
                }

                if (objOptions.HasFlag(ObjOptions.ReverseVertex))
                {
                    // Reverse Vertex Order
                    ObjModifier.ReverseVertexOrder(objData);
                }

                if (objOptions.HasFlag(ObjOptions.Merge))
                {
                    if (mtlData != null)
                    {
                        // Merge groups and materials
                        ObjModifier.MergeGroups(objData, mtlData);
                    }
                    else
                    {
                        warn = true;
                        sb.AppendLine(MessageBoxConstants.MessageErrorMergeGroups + MessageBoxConstants.MessageMtlNotFound);
                    }
                }
                if (objOptions.HasFlag(ObjOptions.Sort))
                {
                    // Sort groups
                    if (!ObjModifier.SortGroups(objData))
                    {
                        warn = true;
                        sb.AppendLine(MessageBoxConstants.MessageErrorSortGroups + MessageBoxConstants.MessageInvalidGroupName);
                    }

                    if (mtlData != null)
                    {
                        // Sort materials
                        if (!ObjModifier.SortMaterials(mtlData))
                        {
                            warn = true;
                            sb.AppendLine(MessageBoxConstants.MessageErrorSortMaterials + MessageBoxConstants.MessageInvalidMaterialName);
                        }
                    }
                    else
                    {
                        warn = true;
                        sb.AppendLine(MessageBoxConstants.MessageErrorSortMaterials + MessageBoxConstants.MessageMtlNotFound);
                    }
                }
                success = ObjExporter.WriteObj(objData, mtlData, objOutput, makeMtl: true, useExistingMtl: true);
                sb.Append(MessageBoxConstants.GetMessageExecutionCreation(success, objOutput));
            }
            else
            {
                sb.Append(MessageBoxConstants.GetMessageExecutionErrorParse(objFile));
            }
            return(new ToolResult(sb.ToString(), success, warn));
        }
Beispiel #22
0
        /// <summary>
        /// Delete all groups that use textures from a given list (compare the textures)
        /// </summary>
        /// <param name="objData">Data parsed from the obj file</param>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        /// <param name="listFileName">List of textures that should be matched</param>
        public static bool DeleteMatchingGroups(ObjData objData, MtlData mtlData, List <string> listFileName)
        {
            if (mtlData == null)
            {
                return(false);
            }

            List <BitmapStoreData> imgList = BitmapStoreData.GetListBitmapStoreData(listFileName);

            var tupleTextureMaterials = MtlUtils.GetTupleDictTextureMaterials(mtlData);

            // Dictionary that associate every texture to a list of materials
            Dictionary <string, List <int> > dictTextureMaterials = tupleTextureMaterials.Item1;
            // List of materials without any texture
            List <int> untexturedMaterials = tupleTextureMaterials.Item2;

            // Dictionary that associate every material to a list of groups
            Dictionary <string, List <int> > dictMaterialGroups = ObjUtils.GetDictMaterialGroups(objData);

            // Dictionary that associate every texture to a list of groups
            Dictionary <string, List <int> > dictTextureGroups = ObjUtils.GetDictTextureGroups(objData, mtlData,
                                                                                               dictTextureMaterials, dictMaterialGroups);

            List <ObjectObj>   newObjectsList   = new List <ObjectObj>();
            List <MaterialMtl> newMaterialsList = new List <MaterialMtl>();

            string srcDir = System.IO.Path.GetDirectoryName(mtlData.FilePath);

            foreach (KeyValuePair <string, List <int> > keyValue in dictTextureGroups)
            {
                List <int> groups = keyValue.Value;
                if (groups != null)
                {
                    if (groups.Count >= 1) // Should always be the case
                    {
                        string texturePath = keyValue.Key;

                        if (!System.IO.Path.IsPathRooted(texturePath)) // Not an absolute path
                        {
                            texturePath = System.IO.Path.Combine(srcDir, texturePath);
                        }

                        System.Drawing.Bitmap img = ImageUtilsShared.CreateBitmap(texturePath);
                        if (img != null)
                        {
                            BitmapStoreData bmpData = new BitmapStoreData(img);
                            if (bmpData.BData != null)
                            {
                                if (!ImageUtilsShared.SamePictures(imgList, bmpData)) // Not the same image
                                {
                                    // We can keep all these groups and materials

                                    foreach (int groupId in groups)
                                    {
                                        ObjectObj objectObj = objData.ObjectsList[groupId];
                                        newObjectsList.Add(objectObj); // Insert the object in the list
                                    }

                                    if (dictTextureMaterials.TryGetValue(keyValue.Key, out List <int> materials))
                                    {
                                        if (materials != null)
                                        {
                                            foreach (int materialId in materials)
                                            {
                                                MaterialMtl materialMtl = mtlData.MaterialsList[materialId];
                                                newMaterialsList.Add(materialMtl); // Insert the material in the list
                                            }
                                        }
                                    }
                                }
                                bmpData.UnlockBits();
                            }
                        }
                    }
                }
            }

            foreach (int materialId in untexturedMaterials) // The untextured materials
            {
                MaterialMtl materialMtl = mtlData.MaterialsList[materialId];
                newMaterialsList.Add(materialMtl); // Insert material in the list
                if (dictMaterialGroups.TryGetValue(materialMtl.NewMtl, out List <int> groups))
                {
                    if (groups != null)
                    {
                        foreach (int groupId in groups)
                        {
                            ObjectObj objectObj = objData.ObjectsList[groupId];
                            newObjectsList.Add(objectObj); // Insert the object in the list
                        }
                    }
                }
            }
            BitmapStoreData.BitmapDataUnlock(imgList);

            objData.ObjectsList   = newObjectsList;
            mtlData.MaterialsList = newMaterialsList;
            return(true);
        }
Beispiel #23
0
        /// <summary>
        /// Merge together groups that share a texture
        /// </summary>
        /// <param name="objData">Data parsed from the obj file</param>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        public static bool MergeGroups(ObjData objData, MtlData mtlData)
        {
            if (mtlData == null)
            {
                return(false);
            }

            var tupleTextureMaterials = MtlUtils.GetTupleDictTextureMaterials(mtlData);

            // Dictionary that associate every texture to a list of materials
            Dictionary <string, List <int> > dictTextureMaterials = tupleTextureMaterials.Item1;

            // List of materials without any texture
            List <int> untexturedMaterials = tupleTextureMaterials.Item2;

            // Dictionary that associate every material to a list of groups
            Dictionary <string, List <int> > dictMaterialGroups = ObjUtils.GetDictMaterialGroups(objData);

            // Dictionary that associate every texture to a list of groups
            Dictionary <string, List <int> > dictTextureGroups = ObjUtils.GetDictTextureGroups(objData, mtlData,
                                                                                               dictTextureMaterials, dictMaterialGroups);

            List <ObjectObj>   newObjectsList   = new List <ObjectObj>();
            List <MaterialMtl> newMaterialsList = new List <MaterialMtl>();

            foreach (KeyValuePair <string, List <int> > keyValue in dictTextureGroups) // Textured groups
            {
                // Merge the groups
                ObjectObj objectObj = MergeObjects(objData, keyValue.Key, keyValue.Value);
                newObjectsList.Add(objectObj);

                if (dictTextureMaterials.TryGetValue(keyValue.Key, out List <int> materials))
                {
                    if (materials != null)
                    {
                        // Merge the materials
                        MaterialMtl materialMtl = MergeMaterials(mtlData, keyValue.Key, materials);
                        newMaterialsList.Add(materialMtl);
                    }
                }
            }

            foreach (int materialId in untexturedMaterials) // The untextured materials
            {
                MaterialMtl materialMtl = mtlData.MaterialsList[materialId];
                newMaterialsList.Add(materialMtl); // Insert material in the list
                if (dictMaterialGroups.TryGetValue(materialMtl.NewMtl, out List <int> groups))
                {
                    if (groups != null)
                    {
                        foreach (int groupId in groups)
                        {
                            ObjectObj objectObj = objData.ObjectsList[groupId];
                            newObjectsList.Add(objectObj); // Insert the object in the list
                        }
                    }
                }
            }
            objData.ObjectsList   = newObjectsList;
            mtlData.MaterialsList = newMaterialsList;
            return(true);
        }
Beispiel #24
0
        /// <summary>
        /// Copy every texture used by the obj file
        /// </summary>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        /// <param name="outputFolder">Where the textures will be copied</param>
        /// <param name="srcDir">Where the textures are located</param>
        /// <returns>True if successful</returns>
        public static bool CopyUsedTextures(MtlData mtlData, string outputFolder, string srcDir)
        {
            if (mtlData == null)
            {
                // No Mtl to read texture data
                return(false);
            }

            bool relative = false;

            if (srcDir == null)
            {
                // If a textureDirectory was not specified, the textures are found relative to the mtl file
                srcDir   = System.IO.Path.GetDirectoryName(mtlData.FilePath);
                relative = true;
            }

            if (!System.IO.Directory.Exists(srcDir))
            {
                // The source directory doesn't exist
                return(false);
            }

            if (!System.IO.Directory.Exists(outputFolder))
            {
                if (!FileUtilsShared.TryCreateDirectory(outputFolder))
                {
                    // Impossible to create the destination directory
                    return(false);
                }
            }

            HashSet <string> texturesList = MtlUtils.GetListTextures(mtlData);

            foreach (string texture in texturesList)
            {
                string srcFile;
                string destFile = System.IO.Path.Combine(outputFolder, System.IO.Path.GetFileName(texture));

                if (relative)                                 // The path to the texture is inside the material
                {
                    if (System.IO.Path.IsPathRooted(texture)) // Absolute path to the picture
                    {
                        srcFile = texture;
                    }
                    else // Relative to the mtl
                    {
                        srcFile = System.IO.Path.Combine(srcDir, texture);
                    }
                }
                else // We find the texture in a given folder
                {
                    srcFile = System.IO.Path.Combine(srcDir, System.IO.Path.GetFileName(texture));
                }

                if (!destFile.Equals(srcFile)) // Destination file is not the Source file
                {
                    if (System.IO.File.Exists(srcFile))
                    {
                        if (System.IO.File.Exists(destFile)) // The destination file already exists, we need to delete it
                        {
                            if (!FileUtilsShared.TryDeleteFile(destFile))
                            {
                                continue; // Impossible to delete the file, we go to the next texture
                            }
                        }
                        FileUtilsShared.TryCopyFile(srcFile, destFile);
                    }
                }
            }
            return(true);
        }