Beispiel #1
0
        private static void LoadLinkedMesh(this IObject3D item, CacheContext cacheContext, CancellationToken cancellationToken, Action <double, string> progress)
        {
            // Abort load if cancel requested
            cancellationToken.ThrowIfCancellationRequested();

            // *************************************************************************
            // TODO: Fix invalid use of Result
            // *************************************************************************
            string filePath = item.ResolveFilePath(progress, cancellationToken).Result;

            if (string.Equals(Path.GetExtension(filePath), ".mcx", StringComparison.OrdinalIgnoreCase))
            {
                var loadedItem = Object3D.Load(filePath, cancellationToken, cacheContext, progress);
                if (loadedItem != null)
                {
                    item.SetMeshDirect(loadedItem.Mesh);

                    // Copy loaded mcx children to source node
                    // TODO: potentially needed for leaf mcx nodes, review and tests required
                    item.Children = loadedItem.Children;
                }
            }
            else
            {
                Mesh mesh = null;

                try
                {
                    if (!cacheContext.Meshes.TryGetValue(filePath, out mesh))
                    {
                        mesh = Object3D.Load(filePath, cancellationToken).Mesh;
                        cacheContext.Meshes[filePath] = mesh;
                    }
                }
                catch
                {
                    // Fall back to Missing mesh if available
                    mesh = Object3D.FileMissingMesh;
                }

                item.SetMeshDirect(mesh);
            }
        }
Beispiel #2
0
        public string StoreStream(Stream stream, string extension)
        {
            // Compute SHA1
            string sha1 = Object3D.ComputeSHA1(stream);

            string fileName  = $"{sha1}{extension}";
            string assetPath = Path.Combine(Object3D.AssetsPath, fileName);

            // Load cache
            if (!File.Exists(assetPath))
            {
                stream.Position = 0;

                using (var outstream = File.OpenWrite(assetPath))
                {
                    stream.CopyTo(outstream);
                }
            }

            return(fileName);
        }
Beispiel #3
0
        public async Task <string> StoreFile(string filePath, bool publishAfterSave, CancellationToken cancellationToken, Action <double, string> progress)
        {
            // Compute SHA1
            string sha1 = Object3D.ComputeFileSHA1(filePath);
            string sha1PlusExtension = sha1 + Path.GetExtension(filePath).ToLower();
            string assetPath         = Path.Combine(Object3D.AssetsPath, sha1PlusExtension);

            // Load cache
            if (!File.Exists(assetPath))
            {
                File.Copy(filePath, assetPath);
            }

            await ConditionalPublish(
                sha1PlusExtension,
                publishAfterSave,
                cancellationToken,
                progress);

            return(sha1PlusExtension);
        }
Beispiel #4
0
        public async Task <string> StoreMcx(IObject3D object3D, bool publishAfterSave)
        {
            // TODO: Track SHA1 of persisted asset
            // TODO: Skip if cached sha1 exists in assets

            // Serialize object3D to in memory mcx/json stream
            using (var memoryStream = new MemoryStream())
            {
                // Write JSON
                object3D.SaveTo(memoryStream);

                // Reposition
                memoryStream.Position = 0;

                Directory.CreateDirectory(Object3D.AssetsPath);

                // Calculate
                string sha1 = Object3D.ComputeSHA1(memoryStream);
                string sha1PlusExtension = sha1 + ".mcx";
                string assetPath         = Path.Combine(Object3D.AssetsPath, sha1PlusExtension);

                if (!File.Exists(assetPath))
                {
                    memoryStream.Position = 0;

                    using (var outStream = File.Create(assetPath))
                    {
                        memoryStream.CopyTo(outStream);
                    }
                }

                await ConditionalPublish(
                    sha1PlusExtension,
                    publishAfterSave,
                    CancellationToken.None,
                    null);

                return(assetPath);
            }
        }
Beispiel #5
0
 public InteractiveScene()
 {
     SourceItem = new Object3D();
 }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }