/// <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> /// 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); }
/// <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); }
private static MaterialMtl MaterialData(List <Tuple <string, string> > listKeysValues, int startIndex, int endIndex) { MaterialMtl materialMtl = new MaterialMtl(); int i = startIndex; while (i < endIndex) { Tuple <string, string> keyValue = listKeysValues[i]; if (keyValue != null) { string key = keyValue.Item1; string value = keyValue.Item2.TrimEnd('\0').Trim(); // Remove the null character and any blank space switch (key) { case "newmtl": materialMtl.NewMtl = value; break; case "Kd": materialMtl.Kd = new Color(value); break; case "Ks": materialMtl.Ks = new Color(value); break; case "Ka": materialMtl.Ka = new Color(value); break; case "Ke": materialMtl.Ke = new Color(value); break; case "Ns": if (Double.TryParse(value, out double tmpDouble)) { materialMtl.Ns = tmpDouble; } break; case "Ni": if (Double.TryParse(value, out tmpDouble)) { materialMtl.Ni = tmpDouble; } break; case "d": if (Double.TryParse(value, out tmpDouble)) { materialMtl.D = tmpDouble; } break; case "illum": if (Int32.TryParse(value, out int tmpInt)) { materialMtl.Illum = tmpInt; } break; case "map_Kd": materialMtl.MapKd = value; break; case "map_Ks": materialMtl.MapKs = value; break; case "map_Ka": materialMtl.MapKa = value; break; case "map_Ke": materialMtl.MapKe = value; break; case "map_d": materialMtl.MapD = value; break; default: break; } } i++; } return(materialMtl); }