private static MeshModel DeserializeComposite(ZipArchive zipFile) { var metadata = MeshModelMetadata.ExtractFrom(zipFile); var partCount = metadata.PartCount; // Vorschaubild lesen byte[] thumbnail = null; if (partCount != 1) { var entry = zipFile.GetEntry("PreviewImage.png"); if (entry != null) { using (var entryStream = entry.Open()) { thumbnail = MeshModelHelper.StreamToArray(entryStream); } } } // Parts lesen var parts = new List <MeshModelPart>(partCount); for (var i = 0; i < partCount; i += 1) { parts.Add(MeshModelPart.Deserialize(zipFile, i.ToString())); } return(new MeshModel(metadata, thumbnail, parts.ToArray())); }
/// <summary> /// Initializes a new instance of the <see cref="MeshModelPart" /> class. /// </summary> /// <param name="metaData">The meta data.</param> private MeshModelPart(MeshModelMetadata metaData) { ConstructGeometry(new Mesh[0], new Edge[0]); Metadata = metaData; UpdateTriangulationHash(); MeshValues = new MeshValueList[0]; Thumbnail = null; }
/// <summary> /// Initializes a new instance of the <see cref="MeshModelPart"/> class. /// </summary> /// <param name="metaData">The meta data.</param> /// <param name="meshes">The meshes.</param> /// <param name="edges">The edges.</param> /// <param name="meshValueLists">A list of data values for this model (deviations, minima, maxima, mean values, etc.).</param> /// <param name="thumbnail">The thumbnail.</param> public MeshModelPart(MeshModelMetadata metaData, IEnumerable <Mesh> meshes, IEnumerable <Edge> edges = null, IEnumerable <MeshValueList> meshValueLists = null, byte[] thumbnail = null) { ConstructGeometry(meshes, edges); Metadata = metaData; UpdateTriangulationHash(); MeshValues = (meshValueLists ?? new MeshValueList[0]).ToArray(); CheckMeshValueIntegrity(); Metadata.MeshValueEntries = MeshValues.Select(m => m.Entry).ToArray(); Thumbnail = thumbnail; }
/// <summary> /// Creates a combined <see cref="MeshModel" /> from the specified <paramref name="parts" />. /// </summary> /// <param name="name">The name for the combined model.</param> /// <param name="thumbnail">The thumbnail for the combined model.</param> /// <param name="parts">The parts.</param> /// <returns></returns> public static MeshModel CreateCombined(string name, byte[] thumbnail, params MeshModelPart[] parts) { if (parts.Length == 0) { return(new MeshModel(new MeshModelMetadata( ), new List <MeshModelPart>())); } if (parts.Length == 1) { return(new MeshModel(parts[0])); } for (var i = 0; i < parts.Length; i += 1) { var part = parts[i]; if (thumbnail == null && part.HasThumbnail) { thumbnail = part.Thumbnail; } } return(new MeshModel(MeshModelMetadata.CreateCombined(name, parts.Select(p => p.Metadata).ToArray()), thumbnail, parts)); }
/// <summary> /// Reads the data from the specified <paramref name="subFolder"/> in the specified <paramref name="zipFile"/> and deserializes the data found in it. /// If no <paramref name="subFolder"/> is specified, the method deserializes the data in the <paramref name="zipFile"/>s root directory. /// </summary> public static MeshModelPart Deserialize(ZipArchive zipFile, string subFolder = "") { var result = new MeshModelPart(new MeshModelMetadata()); var fileVersion10 = new Version(1, 0, 0, 0); // Metadaten lesen using (var entryStream = zipFile.GetEntry(Path.Combine(subFolder, "Metadata.xml")).Open()) { result.Metadata = MeshModelMetadata.ReadFrom(entryStream); } // Versionscheck var fileVersion = result.Metadata.FileVersion; if (fileVersion < fileVersion10) { throw new InvalidOperationException(MeshModelHelper.GetResource <MeshModel>("OldFileVersionError_Text")); } if (fileVersion.Major > MeshModel.MeshModelFileVersion.Major) { throw new InvalidOperationException(MeshModelHelper.FormatResource <MeshModel>("FileVersionError_Text", fileVersion, MeshModel.MeshModelFileVersion)); } // Vorschaubild lesen var thumbnailEntry = zipFile.GetEntry(Path.Combine(subFolder, "PreviewImage.png")); if (thumbnailEntry != null) { using (var entryStream = thumbnailEntry.Open()) { result._Thumbnail = MeshModelHelper.StreamToArray(entryStream); } } // Triangulierungsdaten lesen using (var binaryReader = new BinaryReader(zipFile.GetEntry(Path.Combine(subFolder, "Meshes.dat")).Open())) { var meshCount = binaryReader.ReadInt32(); var meshes = new List <Mesh>(meshCount); for (var i = 0; i < meshCount; i++) { meshes.Add(Mesh.Read(binaryReader, i, fileVersion)); } result.Meshes = meshes.ToArray(); } // Edgedaten lesen using (var binaryReader = new BinaryReader(zipFile.GetEntry(Path.Combine(subFolder, "Edges.dat")).Open())) { var edgeCount = binaryReader.ReadInt32(); var edges = new List <Edge>(edgeCount); for (var i = 0; i < edgeCount; i++) { edges.Add(Edge.Read(binaryReader, fileVersion)); } // we don't try to create a single-point edge result.Edges = edges.Where(e => e.Points?.Length > 3).ToArray(); } // Datenwerte lesen var meshValueList = new List <MeshValueList>(result.Metadata.MeshValueEntries?.Length ?? 0); foreach (var entry in result.Metadata.MeshValueEntries ?? new MeshValueEntry[0]) { using (var binaryReader = new BinaryReader(zipFile.GetEntry(Path.Combine(subFolder, entry.Filename)).Open())) { meshValueList.Add(MeshValueList.Read(binaryReader, entry, fileVersion)); } } result.MeshValues = meshValueList.ToArray(); // falls Guid noch nicht Teil der Metadaten war, dann hier stabile (und hoffentlich eindeutige) Guid den Metadaten zuweisen if (fileVersion < new Version(3, 1, 0, 0)) { result.Metadata.Guid = MeshModelGuidGenerator.GenerateGuids(zipFile.Entries.Where(e => string.Equals(Path.GetDirectoryName(e.FullName), subFolder, StringComparison.OrdinalIgnoreCase))); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="MeshModel" /> class from a set <see cref="MeshModelPart" />. /// </summary> /// <param name="metadata">The metadata.</param> /// <param name="thumbnail">The thumbnail image.</param> /// <param name="parts">The parts.</param> public MeshModel(MeshModelMetadata metadata, byte[] thumbnail, IEnumerable <MeshModelPart> parts) { Parts = new List <MeshModelPart>(parts); Metadata = metadata; Thumbnail = thumbnail; }
/// <summary> /// Initializes a new instance of the <see cref="MeshModel" /> class from a set <see cref="MeshModelPart" />. /// </summary> /// <param name="metaData">The meta data.</param> /// <param name="parts">The parts.</param> public MeshModel(MeshModelMetadata metaData, IEnumerable <MeshModelPart> parts) { Parts = new List <MeshModelPart>(parts); Metadata = metaData; }
/// <summary> /// Initializes a new instance of the <see cref="MeshModel" /> class from a set of triangle meshes and edges. /// </summary> /// <param name="metaData">The meta data.</param> /// <param name="meshes">The triangle meshes.</param> /// <param name="edges">The edges.</param> public MeshModel(MeshModelMetadata metaData, IEnumerable <Mesh> meshes, IEnumerable <Edge> edges) : this(new MeshModelPart(metaData, meshes, edges)) { }
/// <summary> /// Initializes a new instance of the <see cref="MeshModel" /> class from a set of triangle meshes. /// </summary> /// <param name="metaData">The meta data.</param> /// <param name="meshes">The triangle meshes.</param> public MeshModel(MeshModelMetadata metaData, IEnumerable <Mesh> meshes) : this(metaData, meshes, new Edge[0]) { }
/// <summary> /// Deserializes a <see cref="MeshModel"/> from the specified <paramref name="stream"/> /// </summary> public static MeshModel Deserialize(Stream stream) { MeshModel result; if (!stream.CanSeek) { stream = new MemoryStream(MeshModelHelper.StreamToArray(stream)); } using (var zipFile = new ZipArchive(stream)) { // Metadaten lesen MeshModelMetadata metadata; using (var entryStream = zipFile.GetEntry("Metadata.xml").Open()) { metadata = MeshModelMetadata.ReadFrom(entryStream); } var partCount = metadata.PartCount; // Versionscheck var fileVersion = metadata.FileVersion; if (fileVersion == null) { throw new InvalidOperationException(MeshModelHelper.GetResource <MeshModel>("OldFileVersionError_Text")); } if (fileVersion.Major > MeshModelFileVersion.Major) { throw new InvalidOperationException(MeshModelHelper.FormatResource <MeshModel>("FileVersionError_Text", fileVersion, MeshModelFileVersion)); } // Vorschaubild lesen byte[] thumbnail = null; if (partCount != 1) { var entry = zipFile.GetEntry("PreviewImage.png"); if (entry != null) { using (var entryStream = entry.Open()) { thumbnail = MeshModelHelper.StreamToArray(entryStream); } } } // Modelldaten laden if (partCount == 1) { result = new MeshModel(MeshModelPart.Deserialize(zipFile)); } else { var parts = new List <MeshModelPart>(partCount); for (var i = 0; i < partCount; i += 1) { parts.Add(MeshModelPart.Deserialize(zipFile, i.ToString())); } result = new MeshModel(metadata, thumbnail, parts.ToArray()); // falls Guid noch nicht Teil der Metadaten war, dann hier stabile (und hoffentlich eindeutige) Guid den Metadaten zuweisen if (fileVersion < new Version(3, 1, 0, 0)) { metadata.Guid = MeshModelGuidGenerator.GenerateGuids(zipFile.Entries); } } } return(result); }
/// <summary> /// Creates a combined <see cref="MeshModel" /> from the specified <paramref name="models" />. /// </summary> /// <param name="metadata">The metadata for the combined model.</param> /// <param name="thumbnail">The thumbnail for the combined model.</param> /// <param name="models">The models.</param> /// <returns></returns> public static MeshModel CreateCombined(MeshModelMetadata metadata, byte[] thumbnail, params MeshModel[] models) { return(new MeshModel(metadata, thumbnail, models.SelectMany(m => m.Parts).ToArray())); }
/// <summary> /// Initializes this instance with the serialized metadata from the specified <paramref name="stream"/>. /// </summary> public static MeshModelMetadata ReadFrom(Stream stream) { var settings = new XmlReaderSettings { IgnoreComments = true, IgnoreWhitespace = true, IgnoreProcessingInstructions = true, CloseInput = false, NameTable = new NameTable() }; using (var reader = XmlReader.Create(stream, settings)) { var result = new MeshModelMetadata(); reader.MoveToElement(); while (reader.Read()) { switch (reader.Name) { case "Guid": result.Guid = Guid.ParseExact(reader.ReadString(), "N"); break; case "TriangulationHash": result.TriangulationHash = Guid.ParseExact(reader.ReadString(), "N"); break; case "Name": result.Name = reader.ReadString(); break; case "PartCount": result.PartCount = int.Parse(reader.ReadString(), System.Globalization.CultureInfo.InvariantCulture); break; case "FileVersion": result.FileVersion = new Version(reader.ReadString()); break; case "SourceFormat": result.SourceFormat = reader.ReadString(); break; case "Layer": var layer = new List <string>(); while (reader.Read() && reader.NodeType != XmlNodeType.EndElement) { layer.Add(reader.ReadString()); } result.Layer = layer.ToArray(); break; case "SourceModels": var sourceModels = new List <string>(); while (reader.Read() && reader.NodeType != XmlNodeType.EndElement) { sourceModels.Add(reader.ReadString()); } result.SourceModels = sourceModels.ToArray(); break; case "MeshValueEntries": var entries = new List <MeshValueEntry>(); while (reader.Read() && reader.NodeType != XmlNodeType.EndElement) { if (reader.Name == "MeshValueEntry") { entries.Add(MeshValueEntry.Read(reader)); } } result.MeshValueEntries = entries.ToArray(); break; } } return(result); } }
private static MeshModelMetadata ReadFrom(Stream stream, IGuidGenerator fallbackGuidGenerator) { // Needed for later property validation var hasGuid = false; var hasName = false; var hasPartCount = false; var settings = new XmlReaderSettings { IgnoreComments = true, IgnoreWhitespace = true, IgnoreProcessingInstructions = true, CloseInput = false, NameTable = new NameTable() }; using (var reader = XmlReader.Create(stream, settings)) { var result = new MeshModelMetadata(); reader.MoveToElement(); while (reader.Read()) { switch (reader.Name) { case "Guid": result.Guid = Guid.ParseExact(reader.ReadString(), "N"); hasGuid = true; break; case "TriangulationHash": result.TriangulationHash = Guid.ParseExact(reader.ReadString(), "N"); break; case "Name": result.Name = reader.ReadString(); hasName = true; break; case "PartCount": result.PartCount = int.Parse(reader.ReadString(), System.Globalization.CultureInfo.InvariantCulture); hasPartCount = true; break; case "FileVersion": result.FileVersion = new Version(reader.ReadString()); break; case "SourceFormat": result.SourceFormat = reader.ReadString(); break; case "Layer": var layer = new List <string>(); while (reader.Read() && reader.NodeType != XmlNodeType.EndElement) { layer.Add(reader.ReadString()); } result.Layer = layer.ToArray(); break; case "SourceModels": var sourceModels = new List <string>(); while (reader.Read() && reader.NodeType != XmlNodeType.EndElement) { sourceModels.Add(reader.ReadString()); } result.SourceModels = sourceModels.ToArray(); break; case "MeshValueEntries": var entries = new List <MeshValueEntry>(); while (reader.Read() && reader.NodeType != XmlNodeType.EndElement) { if (reader.Name == "MeshValueEntry") { entries.Add(MeshValueEntry.Read(reader)); } } result.MeshValueEntries = entries.ToArray(); break; } } // validation for mendatory properties since version 5.1.0.0 and missing Guid fallback for older versions if (result.FileVersion != null && result.FileVersion >= new Version(5, 1, 0, 0)) { if (!hasGuid) { throw new InvalidOperationException(MeshModelHelper.FormatResource <MeshModel>("InvalidFormatMissingProperty_ErrorText", "Guid")); } if (!hasName) { throw new InvalidOperationException(MeshModelHelper.FormatResource <MeshModel>("InvalidFormatMissingProperty_ErrorText", "Name")); } if (!hasPartCount) { throw new InvalidOperationException(MeshModelHelper.FormatResource <MeshModel>("InvalidFormatMissingProperty_ErrorText", "PartCount")); } } else { if (!hasGuid) { result.Guid = fallbackGuidGenerator.CreateGuid(); } } return(result); } }
/// <summary> /// Reads the data from the specified <paramref name="subFolder"/> in the specified <paramref name="zipFile"/> and deserializes the data found in it. /// If no <paramref name="subFolder"/> is specified, the method deserializes the data in the <paramref name="zipFile"/>s root directory. /// </summary> public static MeshModelPart Deserialize(ZipArchive zipFile, string subFolder = "") { var fileVersion10 = new Version(1, 0, 0, 0); var result = new MeshModelPart(new MeshModelMetadata()); result.Metadata = MeshModelMetadata.ExtractFrom(zipFile, subFolder); // Versionschecks var fileVersion = result.Metadata.FileVersion; if (fileVersion < fileVersion10) { throw new InvalidOperationException(MeshModelHelper.GetResource <MeshModel>("OldFileVersionError_Text")); } if (fileVersion.Major > MeshModel.MeshModelFileVersion.Major) { throw new InvalidOperationException(MeshModelHelper.FormatResource <MeshModel>("FileVersionError_Text", fileVersion, MeshModel.MeshModelFileVersion)); } // Vorschaubild lesen var thumbnailEntry = zipFile.GetEntry(Path.Combine(subFolder, "PreviewImage.png")); if (thumbnailEntry != null) { using (var entryStream = thumbnailEntry.Open()) { result._Thumbnail = MeshModelHelper.StreamToArray(entryStream); } } // Triangulierungsdaten lesen using (var binaryReader = new BinaryReader(zipFile.GetEntry(Path.Combine(subFolder, "Meshes.dat")).Open())) { var meshCount = binaryReader.ReadInt32(); var meshes = new List <Mesh>(meshCount); for (var i = 0; i < meshCount; i++) { meshes.Add(Mesh.Read(binaryReader, i, fileVersion)); } result.Meshes = meshes.ToArray(); } // Edgedaten lesen using (var binaryReader = new BinaryReader(zipFile.GetEntry(Path.Combine(subFolder, "Edges.dat")).Open())) { var edgeCount = binaryReader.ReadInt32(); var edges = new List <Edge>(edgeCount); for (var i = 0; i < edgeCount; i++) { edges.Add(Edge.Read(binaryReader, fileVersion)); } // we don't try to create a single-point edge result.Edges = edges.Where(e => e.Points?.Length > 3).ToArray(); } // Datenwerte lesen var meshValueList = new List <MeshValueList>(result.Metadata.MeshValueEntries?.Length ?? 0); foreach (var entry in result.Metadata.MeshValueEntries ?? new MeshValueEntry[0]) { using (var binaryReader = new BinaryReader(zipFile.GetEntry(Path.Combine(subFolder, entry.Filename)).Open())) { meshValueList.Add(MeshValueList.Read(binaryReader, entry, fileVersion)); } } result.MeshValues = meshValueList.ToArray(); return(result); }