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 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) { if (objExport == null) { SaveObjFile(filePath, meshInfos, type, saveBrushesToTexture, isCollada); 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>(); 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, fi); }
public static void SaveObjFile(string filePath, RenderMesh mesh, MeshType type, ObjExport objExport, 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); }
public static void SaveObjFile(string filePath, List <MeshInfo> meshInfos, MeshType type, ObjExport objExport, RenderMesh mesh) { if (objExport == null) { SaveObjFile(filePath, meshInfos, type); 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>(); 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 (int 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); } String prevGroup = String.Empty; foreach (var materialGroup in objExport.MaterialsGroups) { if (materialGroup.Groups.Count == 0 || !materialGroup.Groups[0].IsValid) { continue; } for (int 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 (int j = group.StartFaceIndex; j <= group.EndFaceIndex; j++) { var face = objExport.Faces[j]; String 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, fi); }
public static void SaveObjFile(string filePath, RenderMesh mesh, MeshType type, ObjExport objExport) { var meshInfos = new List <MeshInfo>(); foreach (var part in mesh.Parts) { meshInfos.Add(new MeshInfo(part)); } SaveObjFile(filePath, meshInfos, type, objExport, mesh); }
public List<DynamicRenderMesh> AddMehes(string path, MeshType type, bool fromDragAndDrop, ManType manType, string animationPath, bool needExporter) { var result = new List<DynamicRenderMesh>(); var objModel = ObjLoader.LoadObjFile(path, needExporter); if (objModel == null) { ProgramCore.EchoToLog(string.Format("Can't load obj model '{0}'", path), EchoMessageType.Error); return result; } switch (type) { case MeshType.Hair: { var fi = new FileInfo(path); var objModelNull = ObjLoader.LoadObjFile(Path.Combine(fi.DirectoryName, fi.Name.Replace(fi.Extension, string.Format("_null{0}", fi.Extension)))); if (objModelNull != null && (objModelNull.Groups.Count != objModel.Groups.Count || objModel.Vertices.Count != objModelNull.Vertices.Count)) // objModel.TextureCoords.Count != objModelNull.TextureCoords.Count)) objModelNull = null; result = LoadHairMeshes(objModel, objModelNull, fromDragAndDrop, manType, MeshType.Hair); foreach (var renderMesh in result) HairMeshes.Add(renderMesh); break; } case MeshType.Accessory: result.AddRange(objModel.accessoryByHeadShop ? LoadSpecialAccessoryMesh(objModel) : new List<DynamicRenderMesh> { LoadAccessoryMesh(objModel) }); break; case MeshType.Head: { var tempPluginTexture = string.Empty; if (ProgramCore.PluginMode) { var folderPath = Path.Combine(Application.StartupPath, "Models\\Model", manType.GetObjDirPath()); switch (ProgramCore.Project.ManType) { case ManType.Male: tempPluginTexture = Path.Combine(folderPath, "Maps", "RyNevio_faceB.jpg"); break; case ManType.Female: tempPluginTexture = Path.Combine(folderPath, "Maps", "RyBelle_face.jpg"); break; case ManType.Child: tempPluginTexture = Path.Combine(folderPath, "Maps", "AC_KidsRRHBy.jpg"); break; default: tempPluginTexture = Path.Combine(Application.StartupPath, "Plugin", "fsRndColor.png"); break; } } foreach (var mesh in HeadMeshes) mesh.Destroy(); HeadMeshes.Clear(); var objModelFull = animationPath == string.Empty ? null : ObjLoader.LoadObjFile(animationPath); if (objModelFull != null && (objModelFull.Groups.Count != objModel.Groups.Count || objModel.Vertices.Count != objModelFull.Vertices.Count || objModel.TextureCoords.Count != objModelFull.TextureCoords.Count)) objModelFull = null; LastTriangleIndex = 0; result = LoadHairMeshes(objModel, objModelFull, fromDragAndDrop, manType, MeshType.Head); var meshPartInfos = new List<MeshPartInfo>(); var a = new Vector3(99999.0f, 99999.0f, 99999.0f); var b = new Vector3(-99999.0f, -99999.0f, -99999.0f); foreach (var renderMesh in result) { HeadMeshes.Add(renderMesh); if (ProgramCore.PluginMode && ProgramCore.MainForm.PluginUvGroups.Contains(renderMesh.Material.Name)) { if (string.IsNullOrEmpty(renderMesh.Material.DiffuseTextureMap)) renderMesh.Material.DiffuseTextureMap = tempPluginTexture; else if (!File.Exists(renderMesh.Material.DiffuseTextureMap)) renderMesh.Material.DiffuseTextureMap = tempPluginTexture; } var meshPartInfo = new MeshPartInfo { VertexPositions = renderMesh.GetVertices(), TextureCoords = renderMesh.GetTexCoords(), PartName = renderMesh.Title, Color = renderMesh.Material.DiffuseColor, Texture = renderMesh.Material.Texture, TransparentTexture = renderMesh.Material.TransparentTexture, TextureName = renderMesh.Material.DiffuseTextureMap, TransparentTextureName = renderMesh.Material.TransparentTextureMap }; // создаем инфу о голове. для работы с headshop GetAABB(ref a, ref b, meshPartInfo.VertexPositions); meshPartInfos.Add(meshPartInfo); } var dv = Vector3.Zero; foreach (var meshPartInfo in meshPartInfos) { dv = MoveToPosition(ref meshPartInfo.VertexPositions, a, b, Vector3.Zero); ProgramCore.MainForm.ctrlRenderControl.headMeshesController.CreateMeshPart(meshPartInfo); } ObjExport = objModel.ObjExport; if (ObjExport != null) ObjExport.Delta = -dv; ProgramCore.MainForm.ctrlRenderControl.headMeshesController.FinishCreating(); // ProgramCore.MainForm.ctrlRenderControl.headMeshesController.InitializeTexturing(HeadController.GetDots(ProgramCore.Project.ManType), HeadController.GetIndices(ProgramCore.Project.ManType)); break; } default: return result; } foreach (var item in result) item.Path = path; return result; }