private static void CheckAndAttachDefaultGroup(ref ObjGroup currentGroup, ref ObjItem result) { if (currentGroup == null) { currentGroup = new ObjGroup("default"); var defaultGroupName = "HeadShopDefaultMaterial".ToLower(); var defaultMaterial = new ObjMaterial(defaultGroupName); result.Groups.Add(defaultMaterial, currentGroup); result.Materials.Add(defaultGroupName, defaultMaterial); } }
public static ObjItem LoadObjFile(string filePath, bool needExporter) { var result = new ObjItem(needExporter); var fi = new FileInfo(filePath); if (!fi.Exists) { return(null); } using (var sr = new StreamReader(fi.FullName, Encoding.Default)) { var currentGroup = default(ObjGroup); CheckAndAttachDefaultGroup(ref currentGroup, ref result); var index = 0; var lastGroupName = String.Empty; if (ProgramCore.PluginMode) { var folderPath = Path.Combine(Application.StartupPath, "Models\\Model", ProgramCore.Project.ManType.GetObjDirPath()); switch (ProgramCore.Project.ManType) { case ManType.Male: LoadMtlib(Path.Combine(folderPath, "Male.mtl"), ref result); break; case ManType.Female: LoadMtlib(Path.Combine(folderPath, "Fem.mtl"), ref result); break; case ManType.Child: LoadMtlib(Path.Combine(folderPath, "Child.mtl"), ref result); break; } } while (!sr.EndOfStream) { var currentLine = sr.ReadLine(); if (String.IsNullOrWhiteSpace(currentLine) || currentLine[0] == '#') { if (currentLine == "#Accessories") { result.accessoryByHeadShop = true; } else if (currentLine == "#HeadShop Model") { result.modelByHeadShop = true; } continue; } var fields = currentLine.Trim().Split(null, 2); if (fields.Length < 2) { ProgramCore.EchoToLog(String.Format("Bad obj file format. File: '{0}'", fi.FullName), EchoMessageType.Warning); continue; } var keyword = fields[0].Trim().ToLower(); var data = fields[1].Trim(); switch (keyword) { case "v": // verticles var vertex = ParseVector3(data); result.Vertices.Add(vertex); if (needExporter) { result.ObjExport.Vertices.Add(vertex); } break; case "vt": // texture coords var textureCoord = ParseTextureCoords(data); result.TextureCoords.Add(textureCoord); if (needExporter) { result.ObjExport.TexCoords.Add(textureCoord); } break; case "vn": // normals var normal = ParseVector3(data); result.Normals.Add(normal); if (needExporter) { result.ObjExport.Normals.Add(normal); } break; case "f": // faces var face = ParceFace(data); if (needExporter) { face.ObjExportIndex = result.ObjExport.Faces.Count; result.ObjExport.Faces.Add(new ObjExportFace(face.Count, face.Vertices)); } currentGroup.AddFace(face); index++; break; case "g": // start group if (needExporter) { lastGroupName = data; if (result.ObjExport.MaterialsGroups.Count > 0) { result.ObjExport.MaterialsGroups.Last().Groups.Last().EndFaceIndex = index - 1; result.ObjExport.MaterialsGroups.Last().Groups.Add(new ObjExportGroup { Group = data, StartFaceIndex = index }); } } break; case "mtllib": //parse mtl file var path = Path.Combine(fi.DirectoryName, data); LoadMtlib(path, ref result); break; case "usemtl": if (needExporter) { if (result.ObjExport.MaterialsGroups.Count > 0) { result.ObjExport.MaterialsGroups.Last().Groups.Last().EndFaceIndex = index - 1; } result.ObjExport.MaterialsGroups.Add(new ObjExportMaterial { Material = data, Groups = new List <ObjExportGroup> { new ObjExportGroup { Group = lastGroupName, StartFaceIndex = index } } }); } var lowerData = data.ToLower(); var materialKey = result.Materials.Keys.SingleOrDefault(x => x == lowerData); ObjMaterial material; if (materialKey == null) // if can't parse mtl, create default group { material = new ObjMaterial(lowerData); result.Materials.Add(lowerData, material); } else { material = result.Materials[materialKey]; } if (result.Groups.ContainsKey(material)) { currentGroup = result.Groups[material]; } else { currentGroup = new ObjGroup(material.Name); result.Groups.Add(material, currentGroup); } break; } } if (result.ObjExport != null && result.ObjExport.MaterialsGroups.Count > 0 && needExporter) { result.ObjExport.MaterialsGroups.Last().Groups.Last().EndFaceIndex = index - 1; } } return(result); }
public static ObjItem LoadObjFile(string filePath, bool needExporter) { var result = new ObjItem(needExporter); var fi = new FileInfo(filePath); if (!fi.Exists) return null; using (var sr = new StreamReader(fi.FullName, Encoding.Default)) { var currentGroup = default(ObjGroup); CheckAndAttachDefaultGroup(ref currentGroup, ref result); var index = 0; var lastGroupName = String.Empty; if (ProgramCore.PluginMode) { var folderPath = Path.Combine(Application.StartupPath, "Models\\Model", ProgramCore.Project.ManType.GetObjDirPath()); switch (ProgramCore.Project.ManType) { case ManType.Male: LoadMtlib(Path.Combine(folderPath, "Male.mtl"), ref result); break; case ManType.Female: LoadMtlib(Path.Combine(folderPath, "Fem.mtl"), ref result); break; case ManType.Child: LoadMtlib(Path.Combine(folderPath, "Child.mtl"), ref result); break; } } while (!sr.EndOfStream) { var currentLine = sr.ReadLine(); if (String.IsNullOrWhiteSpace(currentLine) || currentLine[0] == '#') { if (currentLine == "#Accessories") result.accessoryByHeadShop = true; else if (currentLine == "#HeadShop Model") result.modelByHeadShop = true; continue; } var fields = currentLine.Trim().Split(null, 2); if (fields.Length < 2) { ProgramCore.EchoToLog(String.Format("Bad obj file format. File: '{0}'", fi.FullName), EchoMessageType.Warning); continue; } var keyword = fields[0].Trim().ToLower(); var data = fields[1].Trim(); switch (keyword) { case "v": // verticles var vertex = ParseVector3(data); result.Vertices.Add(vertex); if (needExporter) result.ObjExport.Vertices.Add(vertex); break; case "vt": // texture coords var textureCoord = ParseTextureCoords(data); result.TextureCoords.Add(textureCoord); if (needExporter) result.ObjExport.TexCoords.Add(textureCoord); break; case "vn": // normals var normal = ParseVector3(data); result.Normals.Add(normal); if (needExporter) result.ObjExport.Normals.Add(normal); break; case "f": // faces var face = ParceFace(data); if (needExporter) { face.ObjExportIndex = result.ObjExport.Faces.Count; result.ObjExport.Faces.Add(new ObjExportFace(face.Count, face.Vertices)); } currentGroup.AddFace(face); index++; break; case "g": // start group if (needExporter) { lastGroupName = data; if (result.ObjExport.MaterialsGroups.Count > 0) { result.ObjExport.MaterialsGroups.Last().Groups.Last().EndFaceIndex = index - 1; result.ObjExport.MaterialsGroups.Last().Groups.Add(new ObjExportGroup { Group = data, StartFaceIndex = index }); } } break; case "mtllib": //parse mtl file var path = Path.Combine(fi.DirectoryName, data); LoadMtlib(path, ref result); break; case "usemtl": if (needExporter) { if (result.ObjExport.MaterialsGroups.Count > 0) result.ObjExport.MaterialsGroups.Last().Groups.Last().EndFaceIndex = index - 1; result.ObjExport.MaterialsGroups.Add(new ObjExportMaterial { Material = data, Groups = new List<ObjExportGroup> { new ObjExportGroup { Group = lastGroupName, StartFaceIndex = index } } }); } var lowerData = data.ToLower(); var materialKey = result.Materials.Keys.SingleOrDefault(x => x == lowerData); ObjMaterial material; if (materialKey == null) // if can't parse mtl, create default group { material = new ObjMaterial(lowerData); result.Materials.Add(lowerData, material); } else material = result.Materials[materialKey]; if (result.Groups.ContainsKey(material)) currentGroup = result.Groups[material]; else { currentGroup = new ObjGroup(material.Name); result.Groups.Add(material, currentGroup); } break; } } if (result.ObjExport != null && result.ObjExport.MaterialsGroups.Count > 0 && needExporter) result.ObjExport.MaterialsGroups.Last().Groups.Last().EndFaceIndex = index - 1; } return result; }