public ObjItem(bool needExporter) { ObjExport = needExporter ? new ObjExport() : null; Vertices = new List <Vector3>(); TextureCoords = new List <Vector2>(); Normals = new List <Vector3>(); Groups = new Dictionary <ObjMaterial, ObjGroup>(); Materials = new Dictionary <string, ObjMaterial>(); }
public static void SaveObjFile(string filePath, List <MeshInfo> meshInfos, MeshType type, ObjExport objExport, bool saveBrushesToTexture, bool isCollada, string sessionId) { if (objExport == null) { SaveObjFile(filePath, meshInfos, type, saveBrushesToTexture, isCollada, sessionId); return; } var fi = new FileInfo(filePath); if (fi.Exists) { fi.Delete(); } if (fi.DirectoryName == null) { return; } var mtlPath = Path.Combine(fi.DirectoryName, Path.GetFileNameWithoutExtension(fi.Name) + ".mtl"); var fiMtl = new FileInfo(mtlPath); //if (fiMtl.Exists) // fiMtl.Delete(); var groupIndex = 0; var materials = new Dictionary <string, ObjMaterial>(); var startPositionIndex = 1; var startTexIndex = 1; var startNormalIndex = 1; var indicesPositions = new List <int>(); var indicesTexCoords = new List <int>(); var indicesNormals = new List <int>(); var positions = new List <Vector3>(); var normals = new List <Vector3>(); var texCoords = new List <Vector2>(); Vector3 A = new Vector3(99999.0f, 99999.0f, 99999.0f); Vector3 B = new Vector3(-99999.0f, -99999.0f, -99999.0f); foreach (var meshPartInfo in meshInfos) { PickingController.GetAABB(ref A, ref B, meshPartInfo.Positions); } objExport.SetObjectAABB(A, B); foreach (var meshInfo in meshInfos) // faces should write differently { if (meshInfo.IndicesNormals.Count == 0) { continue; } String groupTitle; if (string.IsNullOrEmpty(meshInfo.Title)) { groupTitle = "Element_" + groupIndex; while (materials.ContainsKey(groupTitle)) { ++groupIndex; groupTitle = "Element_" + groupIndex; } ++groupIndex; } else { groupTitle = meshInfo.Title; } materials.Add(groupTitle, meshInfo.Material); for (var i = 0; i < meshInfo.IndicesTexCoords.Count; i++) { indicesPositions.Add(startPositionIndex + meshInfo.IndicesPositions[i]); indicesTexCoords.Add(startTexIndex + meshInfo.IndicesTexCoords[i]); indicesNormals.Add(startNormalIndex + meshInfo.IndicesNormals[i]); } startPositionIndex += (meshInfo.IndicesPositions.Max() + 1); startTexIndex += (meshInfo.IndicesTexCoords.Max() + 1); startNormalIndex += (meshInfo.IndicesNormals.Max() + 1); positions.AddRange(meshInfo.Positions); normals.AddRange(meshInfo.Normals); texCoords.AddRange(meshInfo.TexCoords); } foreach (var face in objExport.Faces) { var index = face.TriangleIndex0 * 3; for (var l = 0; l < 3; l++) { var v = positions[indicesPositions[index + l] - 1]; var vn = normals[indicesNormals[index + l] - 1]; var vt = texCoords[indicesTexCoords[index + l] - 1]; objExport.SetData(v, vt, vn, face, l); } if (face.VertexCount == 4) { index = face.TriangleIndex1 * 3; var v = positions[indicesPositions[index + 1] - 1]; var vn = normals[indicesNormals[index + 1] - 1]; var vt = texCoords[indicesTexCoords[index + 1] - 1]; objExport.SetData(v, vt, vn, face, 3); } } using (var sw = new StreamWriter(filePath, false, Encoding.Default)) { sw.WriteLine("#Produced by HeadShop"); sw.WriteLine(type == MeshType.Accessory ? "#Accessories" : "#HeadShop Model"); sw.WriteLine("#" + DateTime.Now.ToShortDateString()); sw.WriteLine("mtllib " + fiMtl.Name); sw.WriteLine(); foreach (var v in objExport.Vertices) { var resStr = "v " + v.X.ToString(ProgramCore.Nfi) + " " + v.Y.ToString(ProgramCore.Nfi) + " " + v.Z.ToString(ProgramCore.Nfi); sw.WriteLine(resStr); } foreach (var vt in objExport.TexCoords) { var resStr = "vt " + vt.X.ToString(ProgramCore.Nfi) + " " + vt.Y.ToString(ProgramCore.Nfi); sw.WriteLine(resStr); } foreach (var vn in objExport.Normals) { var resStr = "vn " + vn.X.ToString(ProgramCore.Nfi) + " " + vn.Y.ToString(ProgramCore.Nfi) + " " + vn.Z.ToString(ProgramCore.Nfi); sw.WriteLine(resStr); } var prevGroup = String.Empty; foreach (var materialGroup in objExport.MaterialsGroups) { if (materialGroup.Groups.Count == 0 || !materialGroup.Groups[0].IsValid) { continue; } for (var i = 0; i < materialGroup.Groups.Count; i++) { var group = materialGroup.Groups[i]; if (!group.IsValid) { continue; } if (!prevGroup.Equals(group.Group)) { sw.WriteLine("g " + group.Group); prevGroup = group.Group; } if (i == 0) { sw.WriteLine("usemtl " + materialGroup.Material); } for (var j = group.StartFaceIndex; j <= group.EndFaceIndex; j++) { var face = objExport.Faces[j]; var resStr = "f "; foreach (var vertex in face.FaceVertices) { resStr += (vertex.VertexIndex).ToString(ProgramCore.Nfi); if (objExport.TexCoords.Count > 0) { resStr += "/" + (vertex.TextureIndex).ToString(ProgramCore.Nfi); } if (objExport.Normals.Count > 0) { resStr += "/" + (vertex.NormalIndex).ToString(ProgramCore.Nfi); } resStr += " "; } sw.WriteLine(resStr.Remove(resStr.Length - 1)); } } } } SaveMaterial(mtlPath, materials, type, fi, saveBrushesToTexture, isCollada, string.Empty); }
public static void SaveObjFile(string filePath, RenderMesh mesh, MeshType type, ObjExport objExport, string sessionId, bool saveBrushesToTexture = false, bool isCollada = false) { var meshInfos = new List <MeshInfo>(); foreach (var part in mesh.Parts) { meshInfos.Add(new MeshInfo(part, mesh.MorphScale)); } SaveObjFile(filePath, meshInfos, type, objExport, saveBrushesToTexture, isCollada, sessionId); }