public static IObject3D Load(Stream fileStream, Action <double, string> reportProgress = null, IObject3D source = null) { IObject3D root = source ?? new Object3D(); var time = Stopwatch.StartNew(); // LOAD THE MESH DATA var objFile = new Obj(); objFile.LoadObj(fileStream); IObject3D context = new Object3D(); root.Children.Add(context); var mesh = new Mesh(); context.SetMeshDirect(mesh); foreach (var vertex in objFile.VertexList) { mesh.Vertices.Add(new Vector3Float(vertex.X, vertex.Y, vertex.Z)); } foreach (var face in objFile.FaceList) { for (int i = 0; i < face.VertexIndexList.Length; i++) { if (face.VertexIndexList[i] >= objFile.TextureList.Count) { int a = 0; } } mesh.Faces.Add(face.VertexIndexList[0] - 1, face.VertexIndexList[1] - 1, face.VertexIndexList[2] - 1, mesh.Vertices); if (face.VertexIndexList.Length == 4) { // add the other side of the quad mesh.Faces.Add(face.VertexIndexList[0] - 1, face.VertexIndexList[2] - 1, face.VertexIndexList[3] - 1, mesh.Vertices); } } // load and apply any texture if (objFile.Material != "") { // TODO: have consideration for this being in a shared zip file string pathToObj = Path.GetDirectoryName(((FileStream)fileStream).Name); //Try-catch block for when objFile.Material is not found try { using (var materialsStream = File.OpenRead(Path.Combine(pathToObj, objFile.Material))) { var mtl = new Mtl(); mtl.LoadMtl(materialsStream); foreach (var material in mtl.MaterialList) { if (!string.IsNullOrEmpty(material.DiffuseTextureFileName)) { var pathToTexture = Path.Combine(pathToObj, material.DiffuseTextureFileName); if (File.Exists(pathToTexture)) { var diffuseTexture = new ImageBuffer(); // TODO: have consideration for this being in a shared zip file using (var imageStream = File.OpenRead(pathToTexture)) { if (Path.GetExtension(material.DiffuseTextureFileName).ToLower() == ".tga") { ImageTgaIO.LoadImageData(diffuseTexture, imageStream, 32); } else { ImageIO.LoadImageData(imageStream, diffuseTexture); } } if (diffuseTexture.Width > 0 && diffuseTexture.Height > 0) { int meshFace = 0; for (int objFace = 0; objFace < objFile.FaceList.Count; objFace++, meshFace++) { var face = mesh.Faces[meshFace]; var faceData = objFile.FaceList[objFace]; int textureIndex0 = faceData.TextureVertexIndexList[0] - 1; var uv0 = new Vector2Float(objFile.TextureList[textureIndex0].X, objFile.TextureList[textureIndex0].Y); int textureIndex1 = faceData.TextureVertexIndexList[1] - 1; var uv1 = new Vector2Float(objFile.TextureList[textureIndex1].X, objFile.TextureList[textureIndex1].Y); int textureIndex2 = faceData.TextureVertexIndexList[2] - 1; var uv2 = new Vector2Float(objFile.TextureList[textureIndex2].X, objFile.TextureList[textureIndex2].Y); mesh.FaceTextures.Add(meshFace, new FaceTextureData(diffuseTexture, uv0, uv1, uv2)); if (faceData.TextureVertexIndexList.Length == 4) { meshFace++; int textureIndex3 = faceData.TextureVertexIndexList[3] - 1; var uv3 = new Vector2Float(objFile.TextureList[textureIndex3].X, objFile.TextureList[textureIndex3].Y); mesh.FaceTextures.Add(meshFace, new FaceTextureData(diffuseTexture, uv0, uv2, uv3)); } } context.Color = Color.White; root.Color = Color.White; } } } } } } catch (FileNotFoundException) { // Just continue as if obj.Material == "" to show object } } time.Stop(); Debug.WriteLine(string.Format("OBJ Load in {0:0.00}s", time.Elapsed.TotalSeconds)); time.Restart(); bool hasValidMesh = root.Children.Where(item => item.Mesh.Faces.Count > 0).Any(); Debug.WriteLine("hasValidMesh: " + time.ElapsedMilliseconds); reportProgress?.Invoke(1, ""); return(hasValidMesh ? root : null); }
public static IObject3D Load(Stream fileStream, CancellationToken cancellationToken, Action <double, string> reportProgress = null) { IObject3D root = new Object3D(); IObject3D context = null; int totalMeshes = 0; var time = Stopwatch.StartNew(); var materials = new Dictionary <int, (string name, Color color, int material, PrintOutputTypes output)>(); var itemPropertiesDictionary = new Dictionary <IObject3D, int>(); using (var decompressedStream = GetCompressedStreamIfRequired(fileStream)) { using (var reader = XmlReader.Create(decompressedStream)) { List <Vector3> vertices = null; Mesh mesh = null; var progressData = new ProgressData(fileStream, reportProgress); while (reader.Read()) { if (!reader.IsStartElement()) { continue; } switch (reader.Name) { case "object": break; case "mesh": break; case "vertices": vertices = ReadAllVertices(reader, progressData); break; case "volume": context = new Object3D(); root.Children.Add(context); mesh = new Mesh(); context.SetMeshDirect(mesh); totalMeshes += 1; string materialId; ReadVolume(reader, vertices, mesh, progressData, out materialId); int.TryParse(materialId, out int id); itemPropertiesDictionary.Add(context, id); break; case "material": ReadProperties(reader, materials); break; } } } fileStream.Dispose(); } foreach (var keyValue in itemPropertiesDictionary) { if (materials.TryGetValue(keyValue.Value, out (string name, Color color, int material, PrintOutputTypes output)data)) { keyValue.Key.Name = data.name; keyValue.Key.Color = data.color; keyValue.Key.MaterialIndex = data.material; keyValue.Key.OutputType = data.output; } } time.Stop(); Debug.WriteLine(string.Format("AMF Load in {0:0.00}s", time.Elapsed.TotalSeconds)); time.Restart(); bool hasValidMesh = root.Children.Where(item => item.Mesh.Faces.Count > 0).Any(); Debug.WriteLine("hasValidMesh: " + time.ElapsedMilliseconds); reportProgress?.Invoke(1, ""); return(hasValidMesh ? root : null); }
public static IObject3D Load(Stream fileStream, CancellationToken cancellationToken, Action <double, string> reportProgress = null, IObject3D source = null) { IObject3D root = source ?? new Object3D(); Stopwatch time = Stopwatch.StartNew(); // LOAD THE MESH DATA Obj objFile = new Obj(); objFile.LoadObj(fileStream); IObject3D context = new Object3D(); root.Children.Add(context); var mesh = new Mesh(); context.SetMeshDirect(mesh); foreach (var vertex in objFile.VertexList) { mesh.CreateVertex(vertex.X, vertex.Y, vertex.Z, CreateOption.CreateNew, SortOption.WillSortLater); } foreach (var face in objFile.FaceList) { List <int> zeroBased = new List <int>(face.VertexIndexList.Length); foreach (var index in face.VertexIndexList) { zeroBased.Add(index - 1); } mesh.CreateFace(zeroBased.ToArray(), CreateOption.CreateNew); } // load and apply any texture if (objFile.Material != "") { // TODO: have consideration for this being in a shared zip file string pathToObj = Path.GetDirectoryName(((FileStream)fileStream).Name); using (var materialsStream = File.OpenRead(Path.Combine(pathToObj, objFile.Material))) { var mtl = new Mtl(); mtl.LoadMtl(materialsStream); foreach (var material in mtl.MaterialList) { if (!string.IsNullOrEmpty(material.DiffuseTextureFileName)) { var pathToTexture = Path.Combine(pathToObj, material.DiffuseTextureFileName); if (File.Exists(pathToTexture)) { ImageBuffer diffuseTexture = new ImageBuffer(); // TODO: have consideration for this being in a shared zip file using (var ImageStream = File.OpenRead(pathToTexture)) { if (Path.GetExtension(material.DiffuseTextureFileName).ToLower() == ".tga") { ImageTgaIO.LoadImageData(diffuseTexture, ImageStream, 32); } else { AggContext.ImageIO.LoadImageData(ImageStream, diffuseTexture); } } if (diffuseTexture.Width > 0 && diffuseTexture.Height > 0) { for (int faceIndex = 0; faceIndex < objFile.FaceList.Count; faceIndex++) { var faceData = objFile.FaceList[faceIndex]; var polyFace = mesh.Faces[faceIndex]; polyFace.SetTexture(0, diffuseTexture); int edgeIndex = 0; foreach (FaceEdge faceEdge in polyFace.FaceEdges()) { int textureIndex = faceData.TextureVertexIndexList[edgeIndex] - 1; faceEdge.SetUv(0, new Vector2(objFile.TextureList[textureIndex].X, objFile.TextureList[textureIndex].Y)); edgeIndex++; } } context.Color = Color.White; root.Color = Color.White; } } } } } } time.Stop(); Debug.WriteLine(string.Format("OBJ Load in {0:0.00}s", time.Elapsed.TotalSeconds)); time.Restart(); bool hasValidMesh = root.Children.Where(item => item.Mesh.Faces.Count > 0).Any(); Debug.WriteLine("hasValidMesh: " + time.ElapsedMilliseconds); reportProgress?.Invoke(1, ""); return((hasValidMesh) ? root : null); }
public static IObject3D Load(Stream fileStream, CancellationToken cancellationToken, Action <double, string> reportProgress = null) { IObject3D root = new Object3D(); IObject3D context = null; int totalMeshes = 0; Stopwatch time = Stopwatch.StartNew(); Dictionary <string, ColorF> materials = new Dictionary <string, ColorF>(); Dictionary <IObject3D, string> objectMaterialDictionary = new Dictionary <IObject3D, string>(); using (var decompressedStream = GetCompressedStreamIfRequired(fileStream)) { using (var reader = XmlReader.Create(decompressedStream)) { List <Vector3> vertices = null; Mesh mesh = null; ProgressData progressData = new ProgressData(fileStream, reportProgress); while (reader.Read()) { if (!reader.IsStartElement()) { continue; } switch (reader.Name) { case "object": break; case "mesh": break; case "vertices": vertices = ReadAllVertices(reader, progressData); break; case "volume": context = new Object3D(); root.Children.Add(context); mesh = new Mesh(); context.SetMeshDirect(mesh); totalMeshes += 1; string materialId; ReadVolume(reader, vertices, mesh, progressData, out materialId); objectMaterialDictionary.Add(context, materialId); break; case "material": ReadMaterial(reader, materials); break; } } } fileStream.Dispose(); } foreach (var keyValue in objectMaterialDictionary) { ColorF color = ColorF.White; if (keyValue.Value == null || !materials.TryGetValue(keyValue.Value, out color)) { color = ColorF.White; } keyValue.Key.Color = color.ToColor(); } time.Stop(); Debug.WriteLine(string.Format("AMF Load in {0:0.00}s", time.Elapsed.TotalSeconds)); time.Restart(); bool hasValidMesh = root.Children.Where(item => item.Mesh.Faces.Count > 0).Any(); Debug.WriteLine("hasValidMesh: " + time.ElapsedMilliseconds); reportProgress?.Invoke(1, ""); return((hasValidMesh) ? root : null); }