diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-11-06 02:15:32 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-11-06 02:15:32 +0300 |
commit | a5d979ca00a5a5d957a6b32e10293b1eaf982b20 (patch) | |
tree | 4499fcfe09a08fc6fe667326f8dc35bd5b548135 | |
parent | 485fd2f0cafedd7df3e17753123983d459295e87 (diff) |
Add Mesh format: WRL - Virtual Reality Modeling Language
-rw-r--r-- | UVtools.Core/MeshFormats/MeshFile.cs | 6 | ||||
-rw-r--r-- | UVtools.Core/MeshFormats/WRLMeshFile.cs | 102 |
2 files changed, 106 insertions, 2 deletions
diff --git a/UVtools.Core/MeshFormats/MeshFile.cs b/UVtools.Core/MeshFormats/MeshFile.cs index 2adbea7..595a0c5 100644 --- a/UVtools.Core/MeshFormats/MeshFile.cs +++ b/UVtools.Core/MeshFormats/MeshFile.cs @@ -23,18 +23,20 @@ namespace UVtools.Core.MeshFormats #endregion #region Static - public static string HeaderComment => $"Exported from {About.SoftwareWithVersion} @ {DateTime.UtcNow:u}"; public static readonly FileExtension[] AvailableMeshFiles = { STLMeshFile.FileExtension, Consortium3MFMeshFile.FileExtension, AMFMeshFile.FileExtension, + WRLMeshFile.FileExtension, OBJMeshFile.FileExtension, PLYMeshFile.FileExtension, - OFFMeshFile.FileExtension + OFFMeshFile.FileExtension, }; + public static string HeaderComment => $"Exported from {About.SoftwareWithVersion} @ {DateTime.UtcNow:u}"; + public static FileExtension FindFileExtension(string filePath) { var ext = Path.GetExtension(filePath); diff --git a/UVtools.Core/MeshFormats/WRLMeshFile.cs b/UVtools.Core/MeshFormats/WRLMeshFile.cs new file mode 100644 index 0000000..2109471 --- /dev/null +++ b/UVtools.Core/MeshFormats/WRLMeshFile.cs @@ -0,0 +1,102 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +using System.Collections.Generic; +using System.IO; +using System.Numerics; +using UVtools.Core.Extensions; +using UVtools.Core.FileFormats; + +namespace UVtools.Core.MeshFormats +{ + public class WRLMeshFile : MeshFile + { + #region Members + private readonly Dictionary<Vector3, uint> _vertexCache = new(VertexCacheSize); + private FileStream _triangleStream; + #endregion + + #region Properties + public static FileExtension FileExtension => new(typeof(WRLMeshFile), "wrl", "Virtual Reality Modeling Language"); + #endregion + + #region Constructor + public WRLMeshFile(string filePath, FileMode fileMode, MeshFileFormat fileFormat = MeshFileFormat.ASCII, FileFormat slicerFile = null) : base(filePath, fileMode, MeshFileFormat.ASCII, slicerFile) { } + #endregion + + #region Methods + public override void BeginWrite() + { + /* Create a stream to store the triangles (faces) as they come through */ + _triangleStream = new FileStream(PathExtensions.GetTempFilePathWithExtension("trig", $"{About.Software}_"), FileMode.Create, FileAccess.ReadWrite, FileShare.None, 81920, FileOptions.DeleteOnClose); + + MeshStream.WriteLineLF("#VRML V2.0 utf8"); + MeshStream.WriteLineLF($"WorldInfo {{ info \"{HeaderComment}\" }}"); + MeshStream.WriteLineLF("Shape {"); + MeshStream.WriteLineLF("\tgeometry IndexedFaceSet {"); + MeshStream.WriteLineLF("\t\tcoord Coordinate {"); + MeshStream.WriteString("\t\t\tpoint ["); + } + + public override void WriteTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 normal) + { + if (!_vertexCache.ContainsKey(p1)) + { + MeshStream.WriteString($" {p1.X:F6} {p1.Y:F6} {p1.Z:F6}"); + _vertexCache.Add(p1, VertexCount); + VertexCount++; + } + + if (!_vertexCache.ContainsKey(p2)) + { + MeshStream.WriteString($" {p2.X:F6} {p2.Y:F6} {p2.Z:F6}"); + _vertexCache.Add(p2, VertexCount); + VertexCount++; + } + + if (!_vertexCache.ContainsKey(p3)) + { + MeshStream.WriteString($" {p3.X:F6} {p3.Y:F6} {p3.Z:F6}"); + _vertexCache.Add(p3, VertexCount); + VertexCount++; + } + + _triangleStream.WriteString($" {_vertexCache[p1]} {_vertexCache[p2]} {_vertexCache[p3]} -1"); + + TriangleCount++; + + /* If we are getting close to the cache size. we do *not* want to go over the capacity as that will trigger + * an allocation of a bigger buffer and copy of the kvp's */ + if (_vertexCache.Count >= VertexCacheSize - 10) + { + _vertexCache.Clear(); + } + } + + public override void EndWrite() + { + _vertexCache.Clear(); + + MeshStream.WriteLineLF(" ]"); + MeshStream.WriteLineLF("\t\t}"); + MeshStream.WriteString("\t\tcoordIndex ["); + + + _triangleStream.Seek(0, SeekOrigin.Begin); + _triangleStream.CopyTo(MeshStream); + _triangleStream.Dispose(); + + MeshStream.WriteLineLF(" ]"); + + MeshStream.WriteLineLF("\t}"); + MeshStream.WriteLineLF("}"); + } + + #endregion + } +} |