예제 #1
0
        public void EnsureTexturesAreWrittenTest()
        {
            var file  = new ThreeMfFile();
            var model = new ThreeMfModel();

            model.Resources.Add(new ThreeMfTexture2D(StringToBytes("texture content"), ThreeMfImageContentType.Jpeg));
            file.Models.Add(model);
            using (var archive = GetArchiveFromFile(file))
                using (var modelStream = archive.GetEntry("3D/3dmodel.model").Open())
                    using (var reader = new StreamReader(modelStream))
                    {
                        var modelXml       = XDocument.Parse(reader.ReadToEnd());
                        var textureElement = modelXml.Root.Element(ThreeMfModel.ResourcesName).Element(ThreeMfResource.Texture2DName);

                        // get the path to the texture
                        var path = textureElement.Attribute("path").Value;

                        // ensure it looks correct and isn't an empty guid
                        Assert.NotEqual($"/3D/Textures/{new Guid().ToString("N")}.jpg", path);
                        Assert.StartsWith("/3D/Textures/", path);
                        Assert.EndsWith(".jpg", path);
                        path = path.Substring(1);

                        // ensure that the item is present
                        using (var textureStream = archive.GetEntry(path).Open())
                            using (var textureReader = new StreamReader(textureStream))
                            {
                                // ensure that it's correct
                                Assert.Equal("texture content", textureReader.ReadToEnd());
                            }
                    }
        }
예제 #2
0
        private static ThreeMfFile FileFromParts(params Tuple <string, string>[] filesAndContents)
        {
            using (var ms = new MemoryStream())
            {
                using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
                {
                    var contentTypes = Tuple.Create("[Content_Types].xml", @"
<Types xmlns=""http://schemas.openxmlformats.org/package/2006/content-types"">
  <Default Extension=""rels"" ContentType=""application/vnd.openxmlformats-package.relationships+xml"" />
  <Default Extension=""model"" ContentType=""application/vnd.ms-package.3dmanufacturing-3dmodel+xml"" />
</Types>
");
                    foreach (var pair in filesAndContents.Append(contentTypes))
                    {
                        var path     = pair.Item1;
                        var contents = pair.Item2;
                        var entry    = archive.CreateEntry(path);
                        using (var stream = entry.Open())
                            using (var writer = new StreamWriter(stream))
                            {
                                writer.Write(contents);
                            }
                    }
                }

                ms.Seek(0, SeekOrigin.Begin);
                var file = ThreeMfFile.Load(ms);
                return(file);
            }
        }
예제 #3
0
        public void LoadFromDiskTest()
        {
            var samplesDir  = Path.Combine(Path.GetDirectoryName(typeof(ThreeMfFileLoadTests).GetTypeInfo().Assembly.Location), "Samples");
            var loadedFiles = 0;

            foreach (var path in Directory.EnumerateFiles(samplesDir, "*.3mf", SearchOption.AllDirectories))
            {
                var fileName = Path.GetFileName(path);
                if (fileName == "multiprop-metallic.3mf" || fileName == "multiprop-translucent.3mf")
                {
                    // undefined namespace `ms`
                    continue;
                }

                var pathParts = path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
                if (pathParts.Contains("production") || pathParts.Contains("beam lattice"))
                {
                    // not yet implemented
                    continue;
                }
                if (pathParts.Contains("MUSTFAIL"))
                {
                    // expected to fail
                    continue;
                }
                using (var fs = new FileStream(path, FileMode.Open))
                {
                    var file  = ThreeMfFile.Load(fs);
                    var model = file.Models.Single();
                    loadedFiles++;
                }
            }

            Assert.True(loadedFiles > 0, "No sample files were loaded.  Ensure all submodules have been initialized.");
        }
예제 #4
0
        public void EnsureZeroModelRelationshipsTest()
        {
            var file      = new ThreeMfFile();
            var relsEntry = GetEntryFromFile(file, "_rels/.rels");

            Assert.Null(relsEntry);
        }
예제 #5
0
 private string GetEntryText(ThreeMfFile file, string entryPath)
 {
     using (var archive = GetArchiveFromFile(file))
     {
         return(GetEntryText(archive, entryPath));
     }
 }
예제 #6
0
        public void EnsureModelRelationshipEntryInSavedFileTest()
        {
            var file = new ThreeMfFile();

            using (var ms = new MemoryStream())
            {
                file.Save(ms);
                ms.Seek(0, SeekOrigin.Begin);
                file = ThreeMfFile.Load(ms);
                Assert.Equal(0, file.Models.Count);
            }

            file.Models.Add(new ThreeMfModel());
            using (var ms = new MemoryStream())
            {
                file.Save(ms);
                ms.Seek(0, SeekOrigin.Begin);
                file = ThreeMfFile.Load(ms);
                Assert.Equal(1, file.Models.Count);
            }

            file.Models.Add(new ThreeMfModel());
            using (var ms = new MemoryStream())
            {
                file.Save(ms);
                ms.Seek(0, SeekOrigin.Begin);
                file = ThreeMfFile.Load(ms);
                Assert.Equal(2, file.Models.Count);
            }
        }
예제 #7
0
 private ZipArchiveEntry GetEntryFromFile(ThreeMfFile file, string entryPath)
 {
     using (var archive = GetArchiveFromFile(file))
     {
         return(archive.GetEntry(entryPath));
     }
 }
예제 #8
0
        private ZipArchive GetArchiveFromFile(ThreeMfFile file)
        {
            var ms = new MemoryStream();

            file.Save(ms);
            ms.Seek(0, SeekOrigin.Begin);
            return(GetArchiveFromStream(ms));
        }
예제 #9
0
        public void EnsureModelXmlEncodingTest()
        {
            var file = new ThreeMfFile();

            file.Models.Add(new ThreeMfModel());
            var actual = GetEntryText(file, "3D/3dmodel.model");

            Assert.StartsWith(@"<?xml version=""1.0"" encoding=""utf-8""?>", actual);
        }
예제 #10
0
        private static ThreeMfModel RoundTripModel(ThreeMfModel model)
        {
            var file1 = new ThreeMfFile();

            file1.Models.Add(model);
            var file2 = RoundTripFile(file1);

            return(file2.Models.Single());
        }
예제 #11
0
        public void EnsureMultipleModelRelationshipTest()
        {
            var file = new ThreeMfFile();

            file.Models.Add(new ThreeMfModel());
            file.Models.Add(new ThreeMfModel());
            var relsXml = GetXmlFromFile(file, "_rels/.rels");

            Assert.Equal(2, relsXml.Elements().Count());
        }
 public static ThreeMfFile RoundTripFile(ThreeMfFile file)
 {
     using (var ms = new MemoryStream())
     {
         file.Save(ms);
         ms.Seek(0, SeekOrigin.Begin);
         var file2 = ThreeMfFile.Load(ms);
         return(file2);
     }
 }
예제 #13
0
        public void EnsureSingleModelRelationshipTest()
        {
            var file = new ThreeMfFile();

            file.Models.Add(new ThreeMfModel());
            var relsXml      = GetXmlFromFile(file, "_rels/.rels");
            var relationship = relsXml.Elements().Single();

            Assert.Equal("http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel", relationship.Attribute("Type").Value);
            Assert.Equal("/3D/3dmodel.model", relationship.Attribute("Target").Value);
        }
예제 #14
0
        public void FileSystemAPITest()
        {
            var filePath = Path.GetTempFileName();
            var file     = new ThreeMfFile();

            file.Save(filePath);
            var roundTripFile = ThreeMfFile.Load(filePath);

            try
            {
                File.Delete(filePath);
            }
            catch
            {
            }
        }
예제 #15
0
        public void EnsureContentTypesTest()
        {
            // this file should be static
            var expected = @"
<?xml version=""1.0"" encoding=""utf-8""?>
<Types xmlns=""http://schemas.openxmlformats.org/package/2006/content-types"">
  <Default Extension=""model"" ContentType=""application/vnd.ms-package.3dmanufacturing-3dmodel+xml"" />
  <Default Extension=""rels"" ContentType=""application/vnd.openxmlformats-package.relationships+xml"" />
</Types>
".Trim();
            var file     = new ThreeMfFile();

            file.Models.Add(new ThreeMfModel());
            var actual = GetEntryText(file, "[Content_Types].xml");

            // format contents
            expected = XDocument.Parse(expected).ToString();
            actual   = XDocument.Parse(actual).ToString();
            Assert.Equal(expected, actual);
        }
예제 #16
0
        public void EnsureThumbnailRelationshipsArePresentTest()
        {
            var file  = new ThreeMfFile();
            var model = new ThreeMfModel();

            model.Resources.Add(new ThreeMfObject()
            {
                ThumbnailData = new byte[0], ThumbnailContentType = ThreeMfImageContentType.Jpeg
            });
            model.Resources.Add(new ThreeMfObject()
            {
                ThumbnailData = new byte[0], ThumbnailContentType = ThreeMfImageContentType.Png
            });
            file.Models.Add(model);

            using (var zipStream = new MemoryStream())
                using (var packageStream = new MemoryStream())
                {
                    // save file to stream and duplicate it so it can be re-opened as both a simple zip file and a package to validate structure
                    file.Save(zipStream);
                    zipStream.Seek(0, SeekOrigin.Begin);
                    zipStream.CopyTo(packageStream);
                    zipStream.Seek(0, SeekOrigin.Begin);
                    packageStream.Seek(0, SeekOrigin.Begin);
                    using (var archive = GetArchiveFromStream(zipStream))
                        using (var package = Package.Open(packageStream))
                        {
                            // get the actual thumbnail paths
                            var jpegPath  = "/" + archive.Entries.Single(e => e.Name.EndsWith(".jpg")).FullName;
                            var pngPath   = "/" + archive.Entries.Single(e => e.Name.EndsWith(".png")).FullName;
                            var modelPart = package.GetPart(new Uri("/3D/3dmodel.model", UriKind.RelativeOrAbsolute));
                            var rels      = modelPart.GetRelationships().ToList();
                            Assert.Equal(2, rels.Count);
                            Assert.Equal(jpegPath, rels[0].TargetUri.ToString());
                            Assert.Equal(pngPath, rels[1].TargetUri.ToString());
                        }
                }
        }
예제 #17
0
        public void EnsureTextureRelationshipsArePresentTest()
        {
            var file  = new ThreeMfFile();
            var model = new ThreeMfModel();

            model.Resources.Add(new ThreeMfTexture2D(new byte[0], ThreeMfImageContentType.Jpeg));
            model.Resources.Add(new ThreeMfTexture2D(new byte[0], ThreeMfImageContentType.Png));
            file.Models.Add(model);

            using (var archive = GetArchiveFromFile(file))
            {
                // get the actual texture paths
                var jpegPath = archive.Entries.Single(e => e.Name.EndsWith(".jpg")).FullName;
                var pngPath  = archive.Entries.Single(e => e.Name.EndsWith(".png")).FullName;
                var expected = $@"
<?xml version=""1.0"" encoding=""utf-8""?>
<Relationships xmlns=""http://schemas.openxmlformats.org/package/2006/relationships"">
  <Relationship Type=""http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"" Target=""/{jpegPath}"" Id=""rel1"" />
  <Relationship Type=""http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture"" Target=""/{pngPath}"" Id=""rel2"" />
</Relationships>
".Trim();
                var actual   = GetEntryText(archive, "3D/_rels/3dmodel.model.rels");

                // format contents
                expected = XDocument.Parse(expected).ToString();
                var actualXml = XDocument.Parse(actual);
                var relNumber = 1;
                foreach (var element in actualXml.Root.Elements())
                {
                    // normalize relationship ids
                    element.Attribute("Id").Value = $"rel{relNumber++}";
                }

                actual = actualXml.ToString();
                Assert.Equal(expected, actual);
            }
        }
예제 #18
0
        public void EnsureThumbnailsAreWrittenTest()
        {
            var file  = new ThreeMfFile();
            var obj   = new ThreeMfObject();
            var model = new ThreeMfModel();

            model.Resources.Add(new ThreeMfObject()
            {
                ThumbnailData = StringToBytes("jpeg thumbnail"), ThumbnailContentType = ThreeMfImageContentType.Jpeg
            });
            file.Models.Add(model);
            using (var archive = GetArchiveFromFile(file))
                using (var modelStream = archive.GetEntry("3D/3dmodel.model").Open())
                    using (var reader = new StreamReader(modelStream))
                    {
                        var modelXml      = XDocument.Parse(reader.ReadToEnd());
                        var objectElement = modelXml.Root.Element(ThreeMfModel.ResourcesName).Element(ThreeMfResource.ObjectName);

                        // get the path to the thumbnail
                        var path = objectElement.Attribute("thumbnail").Value;

                        // ensure it looks correct and isn't an empty guid
                        Assert.NotEqual($"{ThreeMfObject.ThumbnailPathPrefix}{new Guid().ToString("N")}.jpg", path);
                        Assert.StartsWith(ThreeMfObject.ThumbnailPathPrefix, path);
                        Assert.EndsWith(".jpg", path);
                        path = path.Substring(1);

                        // ensure that the item is present
                        using (var thumbnailStream = archive.GetEntry(path).Open())
                            using (var thumbnailReader = new StreamReader(thumbnailStream))
                            {
                                // ensure that it's correct
                                Assert.Equal("jpeg thumbnail", thumbnailReader.ReadToEnd());
                            }
                    }
        }
예제 #19
0
        private XElement GetXmlFromFile(ThreeMfFile file, string entryPath)
        {
            var actualText = GetEntryText(file, entryPath);

            return(XDocument.Parse(actualText).Root);
        }