/// <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++; } } }
/// <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); }
/// <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); }
/// <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); }