コード例 #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
        public void WriteComponentTest()
        {
            var model = new ThreeMfModel();
            var first = new ThreeMfObject();

            first.Name = "first";
            model.Resources.Add(first);
            var second = new ThreeMfObject();

            second.Name = "second";
            second.Components.Add(new ThreeMfComponent(first, new ThreeMfMatrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0)));
            model.Resources.Add(second);
            VerifyModelXml(@"
<model>
  <resources>
    <object id=""1"" type=""model"" name=""first"">
      <mesh>
        <vertices />
        <triangles />
      </mesh>
    </object>
    <object id=""2"" type=""model"" name=""second"">
      <mesh>
        <vertices />
        <triangles />
      </mesh>
      <components>
        <component objectid=""1"" transform=""1 2 3 4 5 6 7 8 9 10 11 12"" />
      </components>
    </object>
  </resources>
  <build />
</model>
", model);
        }
コード例 #3
0
        public void WriteObjectPropertiesTest()
        {
            var model         = new ThreeMfModel();
            var obj           = new ThreeMfObject();
            var baseMaterials = new ThreeMfBaseMaterials();

            baseMaterials.Bases.Add(new ThreeMfBase("blue", new ThreeMfsRGBColor(0, 0, 255)));
            obj.PropertyResource = baseMaterials;
            obj.PropertyIndex    = 0;
            model.Resources.Add(obj);

            // `baseMaterials` was never added to the model resources; ensure it is when writing
            VerifyModelXml(@"
<model>
  <resources>
    <basematerials id=""1"">
      <base name=""blue"" displaycolor=""#0000FFFF"" />
    </basematerials>
    <object id=""2"" type=""model"" pid=""1"" pindex=""0"">
      <mesh>
        <vertices />
        <triangles />
      </mesh>
    </object>
  </resources>
  <build />
</model>
", model);
        }
コード例 #4
0
        public void WriteBuildItemWithTransformMatrixTest()
        {
            var model = new ThreeMfModel();
            var obj   = new ThreeMfObject();

            model.Resources.Add(obj);
            model.Items.Add(new ThreeMfModelItem(obj)
            {
                Transform = new ThreeMfMatrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0)
            });
            VerifyModelXml(@"
<model>
  <resources>
    <object id=""1"" type=""model"">
      <mesh>
        <vertices />
        <triangles />
      </mesh>
    </object>
  </resources>
  <build>
    <item objectid=""1"" transform=""1 2 3 4 5 6 7 8 9 10 11 12"" />
  </build>
</model>
", model);
        }
コード例 #5
0
        public void WriteBuildItemTest()
        {
            var model = new ThreeMfModel();
            var obj   = new ThreeMfObject();

            model.Resources.Add(obj);
            model.Items.Add(new ThreeMfModelItem(obj)
            {
                PartNumber = "part number"
            });
            VerifyModelXml(@"
<model>
  <resources>
    <object id=""1"" type=""model"">
      <mesh>
        <vertices />
        <triangles />
      </mesh>
    </object>
  </resources>
  <build>
    <item objectid=""1"" partnumber=""part number"" />
  </build>
</model>
", model);
        }
コード例 #6
0
        private static ThreeMfModel RoundTripModel(ThreeMfModel model)
        {
            var file1 = new ThreeMfFile();

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

            return(file2.Models.Single());
        }
コード例 #7
0
        public void TextureRoundTripTest()
        {
            var model1 = new ThreeMfModel();

            model1.Resources.Add(new ThreeMfTexture2D(StringToBytes("jpeg texture"), ThreeMfImageContentType.Jpeg));
            var model2 = RoundTripModel(model1);

            Assert.Equal("jpeg texture", BytesToString(model2.Resources.Cast <ThreeMfTexture2D>().Single().TextureBytes));
        }
コード例 #8
0
        private string GetStrippedModelXml(ThreeMfModel model)
        {
            // don't want to specify the defaults in every test
            var dummyPackage = Package.Open(new MemoryStream(), FileMode.Create);

            return(StripXmlns(model.ToXElement(dummyPackage).ToString())
                   .Replace(@" xml:lang=""en-US""", "")
                   .Replace(@" unit=""millimeter""", ""));
        }
コード例 #9
0
        public void ThumbnailRoundTripTest()
        {
            var model1 = new ThreeMfModel();

            model1.Resources.Add(new ThreeMfObject()
            {
                ThumbnailData = StringToBytes("jpeg thumbnail"), ThumbnailContentType = ThreeMfImageContentType.Jpeg
            });
            var model2 = RoundTripModel(model1);

            Assert.Equal("jpeg thumbnail", BytesToString(model2.Resources.Cast <ThreeMfObject>().Single().ThumbnailData));
        }
コード例 #10
0
        public void WriteMetadataTest()
        {
            var model = new ThreeMfModel();

            model.Title       = "some title";
            model.Description = "line 1\nline 2";
            VerifyModelXml(@"
<model>
  <metadata name=""Title"">some title</metadata>
  <metadata name=""Description"">line 1</metadata>
  <metadata name=""Description"">line 2</metadata>
  <resources />
  <build />
</model>
", model);
        }
コード例 #11
0
        public void WriteColorGroupTest()
        {
            var model      = new ThreeMfModel();
            var colorGroup = new ThreeMfColorGroup();

            colorGroup.Colors.Add(new ThreeMfColor(new ThreeMfsRGBColor(0, 0, 255)));
            model.Resources.Add(colorGroup);
            VerifyModelXml($@"
<model xmlns:m=""{ThreeMfModel.MaterialNamespace}"">
  <resources>
    <m:colorgroup id=""1"">
      <m:color color=""#0000FFFF"" />
    </m:colorgroup>
  </resources>
  <build />
</model>
", model);
        }
コード例 #12
0
        public void IncludeAllResourcesTest()
        {
            // ensure that improperly built models still write out all resources
            var model = new ThreeMfModel();
            var obj   = new ThreeMfObject()
            {
                Name = "build item"
            };

            obj.Components.Add(new ThreeMfComponent(new ThreeMfObject()
            {
                Name = "component"
            }, ThreeMfMatrix.Identity));
            model.Items.Add(new ThreeMfModelItem(obj));

            // note that as of here, no objects have ever been added to `model.Resources`
            Assert.Equal(0, model.Resources.Count);

            // but calling `.ToXElement()` will force it to be populated appropriately
            VerifyModelXml(@"
<model>
  <resources>
    <object id=""1"" type=""model"" name=""component"">
      <mesh>
        <vertices />
        <triangles />
      </mesh>
    </object>
    <object id=""2"" type=""model"" name=""build item"">
      <mesh>
        <vertices />
        <triangles />
      </mesh>
      <components>
        <component objectid=""1"" />
      </components>
    </object>
  </resources>
  <build>
    <item objectid=""2"" />
  </build>
</model>
", model);
        }
コード例 #13
0
        internal static ThreeMfModel ParseXml(string contents, params Tuple <string, string, byte[]>[] packageEntries)
        {
            var document     = XDocument.Parse(contents);
            var dummyPackage = Package.Open(new MemoryStream(), FileMode.Create);

            foreach (var packageEntry in packageEntries)
            {
                var uri         = packageEntry.Item1;
                var contentType = packageEntry.Item2;
                var data        = packageEntry.Item3;
                var packagePart = dummyPackage.CreatePart(new Uri(uri, UriKind.RelativeOrAbsolute), contentType);
                using (var partStream = packagePart.GetStream())
                {
                    partStream.Write(data, 0, data.Length);
                }
            }

            return(ThreeMfModel.LoadXml(document.Root, dummyPackage));
        }
コード例 #14
0
        public void WriteSimpleModelTest()
        {
            var model = new ThreeMfModel();

            model.ModelUnits = ThreeMfModelUnits.Inch;
            model.Resources.Add(new ThreeMfObject());
            VerifyModelXml(@"
<model unit=""inch"">
  <resources>
    <object id=""1"" type=""model"">
      <mesh>
        <vertices />
        <triangles />
      </mesh>
    </object>
  </resources>
  <build />
</model>
", model);
        }
コード例 #15
0
        public void WriteBaseMaterialsTest()
        {
            var model         = new ThreeMfModel();
            var baseMaterials = new ThreeMfBaseMaterials();

            baseMaterials.Bases.Add(new ThreeMfBase("blue", new ThreeMfsRGBColor(0, 0, 255)));
            baseMaterials.Bases.Add(new ThreeMfBase("green no alpha", new ThreeMfsRGBColor(0, 255, 0, 0)));
            model.Resources.Add(baseMaterials);
            VerifyModelXml(@"
<model>
  <resources>
    <basematerials id=""1"">
      <base name=""blue"" displaycolor=""#0000FFFF"" />
      <base name=""green no alpha"" displaycolor=""#00FF0000"" />
    </basematerials>
  </resources>
  <build />
</model>
", model);
        }
コード例 #16
0
        public void WriteTexture2DGroupTest()
        {
            var model        = new ThreeMfModel();
            var textureGroup = new ThreeMfTexture2DGroup(new ThreeMfTexture2D(new byte[0], ThreeMfImageContentType.Jpeg));

            textureGroup.Coordinates.Add(new ThreeMfTexture2DCoordinate(1.0, 2.0));
            model.Resources.Add(textureGroup);

            // texture was never added to the texture group; ensure it is when writing
            var text = GetStrippedModelXml(model);

            Assert.EndsWith(@"
.jpg"" contenttype=""image/jpeg"" />
    <m:texture2dgroup id=""2"" texid=""1"">
      <m:tex2coord u=""1"" v=""2"" />
    </m:texture2dgroup>
  </resources>
  <build />
</model>
".Trim(), text);
        }
コード例 #17
0
        public void WriteTriangleVertexPropertiesTest()
        {
            var model         = new ThreeMfModel();
            var obj           = new ThreeMfObject();
            var baseMaterials = new ThreeMfBaseMaterials();

            baseMaterials.Bases.Add(new ThreeMfBase("blue", new ThreeMfsRGBColor(0, 0, 255)));
            var triangle = new ThreeMfTriangle(new ThreeMfVertex(0, 0, 0), new ThreeMfVertex(1, 1, 1), new ThreeMfVertex(2, 2, 2));

            triangle.PropertyResource = baseMaterials;
            triangle.V1PropertyIndex  = 0;
            triangle.V2PropertyIndex  = null;
            triangle.V3PropertyIndex  = null;
            obj.Mesh.Triangles.Add(triangle);
            model.Resources.Add(obj);

            // `baseMaterials` was never added to the model resources; ensure it is when writing
            VerifyModelXml(@"
<model>
  <resources>
    <basematerials id=""1"">
      <base name=""blue"" displaycolor=""#0000FFFF"" />
    </basematerials>
    <object id=""2"" type=""model"">
      <mesh>
        <vertices>
          <vertex x=""0"" y=""0"" z=""0"" />
          <vertex x=""1"" y=""1"" z=""1"" />
          <vertex x=""2"" y=""2"" z=""2"" />
        </vertices>
        <triangles>
          <triangle v1=""0"" v2=""1"" v3=""2"" pid=""1"" p1=""0"" />
        </triangles>
      </mesh>
    </object>
  </resources>
  <build />
</model>
", model);
        }
コード例 #18
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());
                        }
                }
        }
コード例 #19
0
        public void WriteTexture2DTest()
        {
            var model   = new ThreeMfModel();
            var texture = new ThreeMfTexture2D(new byte[0], ThreeMfImageContentType.Jpeg);

            texture.BoundingBox = new ThreeMfBoundingBox(0.0, 1.0, 2.0, 3.0);
            texture.TileStyleU  = ThreeMfTileStyle.Mirror;
            model.Resources.Add(texture);
            var text = GetStrippedModelXml(model);

            // texture path is randomly generated so we have to check before and after it
            Assert.StartsWith($@"
<model xmlns:m=""{ThreeMfModel.MaterialNamespace}"">
  <resources>
    <m:texture2d id=""1"" path=""/3D/Textures/
".Trim(), text);
            Assert.EndsWith(@"
.jpg"" contenttype=""image/jpeg"" box=""0 1 2 3"" tilestyleu=""mirror"" />
  </resources>
  <build />
</model>
".Trim(), text);
        }
コード例 #20
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);
            }
        }
コード例 #21
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());
                            }
                    }
        }
コード例 #22
0
        private void VerifyModelXml(string xml, ThreeMfModel model)
        {
            var actual = GetStrippedModelXml(model);

            Assert.Equal(xml.Trim(), actual);
        }