/* * GNU AFFERO GENERAL PUBLIC LICENSE * Version 3, 19 November 2007 * Copyright (C) 2007 Free Software Foundation, Inc. * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. */ using System; using System.ComponentModel; using System.IO; using System.Linq; using System.Numerics; using UVtools.Core.Extensions; using UVtools.Core.FileFormats; namespace UVtools.Core.MeshFormats; public abstract class MeshFile : IDisposable { #region Constants public const int VertexCacheSize = 84000; // About 1MB #endregion #region Static public static readonly FileExtension[] AvailableMeshFiles = { STLMeshFile.FileExtension, Consortium3MFMeshFile.FileExtension, AMFMeshFile.FileExtension, WRLMeshFile.FileExtension, OBJMeshFile.FileExtension, PLYMeshFile.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); return AvailableMeshFiles.FirstOrDefault(fileExtension => $".{fileExtension.Extension}" == ext); } public static MeshFile? CreateInstance(string filePath, FileMode fileMode, MeshFileFormat fileFormat = MeshFileFormat.BINARY, FileFormat? slicerFile = null) { var fileExtension = FindFileExtension(filePath); return fileExtension?.FileFormatType.CreateInstance(filePath, fileMode, fileFormat, slicerFile!); } #endregion #region Enums public enum MeshFileFormat : byte { [Description("Binary")] BINARY, [Description("ASCII")] ASCII } #endregion #region Properties /// /// Gets the file format for this mesh /// public MeshFileFormat FileFormat { get; } = MeshFileFormat.BINARY; /// /// Gets the from model export /// public FileFormat? SlicerFile { get; } /// /// Gets the file path of the stream /// public string FilePath { get; } /// /// Gets the file name with extension from /// public string Filename => Path.GetFileName(FilePath); public string FilenameWithoutExtension => Path.GetFileNameWithoutExtension(FilePath); /// /// Gets the current file stream /// public FileStream MeshStream { get; } /// /// Gets the number of vertexes, this is often triangle count * 3 /// public uint VertexCount { get; protected set; } /// /// Gets the number of triangles /// public uint TriangleCount { get; protected set; } #endregion #region Constructor protected MeshFile(string filePath, FileMode fileMode, MeshFileFormat meshFileFormat = MeshFileFormat.BINARY, FileFormat? slicerFile = null) { FilePath = filePath; FileFormat = meshFileFormat; SlicerFile = slicerFile; MeshStream = new FileStream(filePath, fileMode); } #endregion #region Methods /// /// Call once before write content to the file, use this to build up the header if any /// public virtual void BeginWrite(){} /// /// Writes an triangle to the file /// /// /// /// /// public abstract void WriteTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 normal); /// /// Call once before close the file, use this to build up the footer if any /// public virtual void EndWrite(){} /// public void Dispose() { MeshStream?.Dispose(); } #endregion }