/// <summary> /// Opens the specified stream, s. Note that as a Portable class library /// </summary> /// <param name="s">The s.</param> /// <param name="filename">The filename.</param> /// <param name="solid">The solid.</param> /// <returns>TessellatedSolid.</returns> /// <exception cref="Exception">Cannot open file without extension (e.g. f00.stl). /// or /// This function has been recently removed. /// or /// Cannot determine format from extension (not .stl, .ply, .3ds, .lwo, .obj, .objx, or .off.</exception> /// <exception cref="System.Exception">Cannot open file without extension (e.g. f00.stl). /// or /// This function has been recently removed. /// or /// Cannot determine format from extension (not .stl, .ply, .3ds, .lwo, .obj, .objx, or .off.</exception> public static void Open(Stream s, string filename, out TessellatedSolid solid) { var extension = GetExtensionFromFileName(filename); switch (extension) { case "stl": solid = STLFileData.OpenSolids(s, filename)[0]; // Standard Tessellation or StereoLithography break; case "3mf": #if net40 throw new NotSupportedException("The loading or saving of .3mf files are not supported in the .NET4.0 version of TVGL."); #else solid = ThreeMFFileData.OpenSolids(s, filename)[0]; break; #endif case "model": solid = ThreeMFFileData.OpenModelFile(s, filename)[0]; break; case "amf": solid = AMFFileData.OpenSolids(s, filename)[0]; break; case "off": solid = OFFFileData.OpenSolid(s, filename); // http://en.wikipedia.org/wiki/OFF_(file_format) break; case "ply": solid = PLYFileData.OpenSolid(s, filename); break; case "shell": solid = ShellFileData.OpenSolids(s, filename)[0]; break; case "xml": solid = (TessellatedSolid)TVGLFileData.OpenSolids(s, filename)[0]; break; default: throw new Exception( "Cannot determine format from extension (not .stl, .ply, .3ds, .lwo, .obj, .objx, or .off."); } }
private static TVGLFileData MakeFileData(TessellatedSolid ts) { var result = new TVGLFileData { Center = ts.Center, ConvexHullCenter = ts.ConvexHull.Center, ConvexHullArea = ts.ConvexHull.SurfaceArea, ConvexHullVolume = ts.ConvexHull.Volume, HasUniformColor = ts.HasUniformColor, Language = ts.Language, Mass = ts.Mass, Name = ts.Name, Primitives = ts.Primitives, SameTolerance = ts.SameTolerance, SurfaceArea = ts.SurfaceArea, Units = ts.Units, Volume = ts.Volume, XMax = ts.XMax, XMin = ts.XMin, YMax = ts.YMax, YMin = ts.YMin, ZMax = ts.ZMax, ZMin = ts.ZMin, ConvexHullVertices = string.Join(",", ts.ConvexHull.Vertices.Select(v => v.IndexInList)), ConvexHullFaces = string.Join(",", ts.ConvexHull.Faces.SelectMany(face => face.Vertices.Select(v => v.IndexInList))), Faces = string.Join(",", ts.Faces.SelectMany(face => face.Vertices.Select(v => v.IndexInList))), Vertices = string.Join(",", ts.Vertices.SelectMany(v => v.Position)) }; result.Colors = result.HasUniformColor ? ts.SolidColor.ToString() : string.Join(",", ts.Faces.Select(f => f.Color)); result.Comments.AddRange(ts.Comments); if (ts._inertiaTensor != null) { var tensorAsArray = new double[9]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { tensorAsArray[3 * i + j] = ts._inertiaTensor[i, j]; } } result.InertiaTensor = string.Join(",", tensorAsArray); } return(result); }
/// <summary> /// Saves the specified stream. /// </summary> /// <param name="stream">The stream.</param> /// <param name="solid">The solid.</param> /// <param name="fileType">Type of the file.</param> /// <returns>System.Boolean.</returns> public static bool Save(Stream stream, Solid solid, FileType fileType = FileType.TVGL) { if (solid is TessellatedSolid) { var ts = (TessellatedSolid)solid; switch (fileType) { case FileType.STL_ASCII: return(STLFileData.SaveASCII(stream, new[] { ts })); case FileType.STL_Binary: return(STLFileData.SaveBinary(stream, new[] { ts })); case FileType.AMF: return(AMFFileData.SaveSolids(stream, new[] { ts })); case FileType.ThreeMF: #if net40 throw new NotSupportedException("The loading or saving of .3mf files are not allowed in the .NET4.0 version of TVGL."); #else return(ThreeMFFileData.Save(stream, new[] { ts })); #endif case FileType.Model3MF: return(ThreeMFFileData.SaveModel(stream, new[] { ts })); case FileType.OFF: return(OFFFileData.SaveSolid(stream, ts)); case FileType.PLY_ASCII: return(PLYFileData.SaveSolidASCII(stream, ts)); case FileType.PLY_Binary: return(PLYFileData.SaveSolidBinary(stream, ts)); default: return(TVGLFileData.SaveSolid(stream, ts)); } } if (solid is VoxelizedSolid) { return(TVGLFileData.SaveSolid(stream, (VoxelizedSolid)solid)); } return(false); }
public static void Open(Stream s, string filename, out TessellatedSolid[] tessellatedSolids) { var extension = GetExtensionFromFileName(filename); switch (extension) { case "stl": tessellatedSolids = STLFileData.OpenSolids(s, filename); // Standard Tessellation or StereoLithography break; case "3mf": #if net40 throw new NotSupportedException("The loading or saving of .3mf files are not supported in the .NET4.0 version of TVGL."); #else tessellatedSolids = ThreeMFFileData.OpenSolids(s, filename); break; #endif case "model": tessellatedSolids = ThreeMFFileData.OpenModelFile(s, filename); break; case "amf": tessellatedSolids = AMFFileData.OpenSolids(s, filename); break; case "shell": tessellatedSolids = ShellFileData.OpenSolids(s, filename); break; case "xml": tessellatedSolids = TVGLFileData.OpenSolids(s, filename).Cast <TessellatedSolid>().ToArray(); break; default: throw new Exception( "Cannot determine format from extension (not .stl, .ply, .3ds, .lwo, .obj, .objx, or .off."); } }
public static void Open(Stream s, string filename, out VoxelizedSolid[] solids) { solids = TVGLFileData.OpenSolids(s, filename).Cast <VoxelizedSolid>().ToArray(); }
public static void Open(Stream s, string filename, out VoxelizedSolid solid) { solid = (VoxelizedSolid)TVGLFileData.OpenSolids(s, filename)[0]; }
/// <summary> /// Saves the specified stream. /// </summary> /// <param name="stream">The stream.</param> /// <param name="solids">The solids.</param> /// <param name="fileType">Type of the file.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public static bool Save(Stream stream, IList <Solid> solids, FileType fileType = FileType.TVGL) { if (solids.Count == 0) { return(false); } if (solids.All(s => s is TessellatedSolid)) { var tessellatedSolids = solids.Cast <TessellatedSolid>().ToArray(); switch (fileType) { case FileType.STL_ASCII: return(STLFileData.SaveASCII(stream, tessellatedSolids)); case FileType.STL_Binary: return(STLFileData.SaveBinary(stream, tessellatedSolids)); case FileType.AMF: return(AMFFileData.SaveSolids(stream, tessellatedSolids)); case FileType.ThreeMF: #if net40 throw new NotSupportedException("The loading or saving of .3mf files are not allowed in the .NET4.0 version of TVGL."); #else return(ThreeMFFileData.Save(stream, tessellatedSolids)); #endif case FileType.Model3MF: return(ThreeMFFileData.SaveModel(stream, tessellatedSolids)); case FileType.OFF: if (solids.Count > 1) { throw new NotSupportedException( "The OFF format does not support saving multiple solids to a single file."); } else { return(OFFFileData.SaveSolid(stream, tessellatedSolids[0])); } case FileType.PLY_ASCII: if (solids.Count > 1) { throw new NotSupportedException( "The PLY format does not support saving multiple solids to a single file."); } else { return(PLYFileData.SaveSolidASCII(stream, tessellatedSolids[0])); } case FileType.PLY_Binary: if (solids.Count > 1) { throw new NotSupportedException( "The PLY format does not support saving multiple solids to a single file."); } else { return(PLYFileData.SaveSolidBinary(stream, tessellatedSolids[0])); } default: if (solids.Count > 1) { return(TVGLFileData.SaveSolids(stream, tessellatedSolids)); } else { return(TVGLFileData.SaveSolid(stream, tessellatedSolids[0])); } } } if (solids.All(s => s is VoxelizedSolid)) { var tessellatedSolids = solids.Cast <VoxelizedSolid>().ToArray(); if (solids.Count > 1) { return(TVGLFileData.SaveSolids(stream, solids.Cast <VoxelizedSolid>().ToArray())); } else { return(TVGLFileData.SaveSolid(stream, (VoxelizedSolid)solids[0])); } } return(false); }
private static TVGLFileData MakeFileData(VoxelizedSolid vs) { double[] ConvexHullCenter; double ConvexHullArea; double ConvexHullVolume; if (vs.ConvexHull is null) { ConvexHullCenter = null; ConvexHullArea = 0; ConvexHullVolume = 0; } else { ConvexHullCenter = vs.ConvexHull.Center; ConvexHullArea = vs.ConvexHull.SurfaceArea; ConvexHullVolume = vs.ConvexHull.Volume; } var result = new TVGLFileData { Center = vs.Center, ConvexHullCenter = ConvexHullCenter, ConvexHullArea = ConvexHullArea, ConvexHullVolume = ConvexHullVolume, HasUniformColor = true, Language = vs.Language, Mass = vs.Mass, Name = vs.Name, Primitives = vs.Primitives, SurfaceArea = vs.SurfaceArea, Units = vs.Units, Volume = vs.Volume, XMax = vs.XMax, XMin = vs.XMin, YMax = vs.YMax, YMin = vs.YMin, ZMax = vs.ZMax, ZMin = vs.ZMin, BitLevelDistribution = (int[])vs.bitLevelDistribution.Clone() }; result.Voxels = new string[vs.bitLevelDistribution.Length]; for (int i = 0; i < vs.NumberOfLevels; i++) { var byteArray = (vs.Voxels(i, true) .SelectMany(v => BitConverter.GetBytes(v.ID))).ToArray(); result.Voxels[i] = BitConverter.ToString(byteArray).Replace("-", ""); } result.Colors = vs.SolidColor.ToString(); result.Comments.AddRange(vs.Comments); if (vs._inertiaTensor != null) { var tensorAsArray = new double[9]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { tensorAsArray[3 * i + j] = vs._inertiaTensor[i, j]; } } result.InertiaTensor = string.Join(",", tensorAsArray); } return(result); }
internal VoxelizedSolid(TVGLFileData fileData, string fileName) : base(fileData, fileName) { bitLevelDistribution = fileData.BitLevelDistribution; Discretization = bitLevelDistribution.Sum(); voxelsPerSide = bitLevelDistribution.Select(b => (int)Math.Pow(2, b)).ToArray(); voxelsInParent = voxelsPerSide.Select(s => s * s * s).ToArray(); defineMaskAndShifts(bitLevelDistribution); numberOfLevels = bitLevelDistribution.Length; // the next 10 lines are common to the constructor above. They cannot be combines since these // flow down to different sub-constructors dimensions = new double[3]; for (int i = 0; i < 3; i++) { dimensions[i] = Bounds[1][i] - Bounds[0][i]; } var longestSide = dimensions.Max(); longestDimensionIndex = dimensions.FindIndex(d => d == longestSide); longestSide = Bounds[1][longestDimensionIndex] - Bounds[0][longestDimensionIndex]; VoxelSideLengths = new double[numberOfLevels]; VoxelSideLengths[0] = longestSide / voxelsPerSide[0]; for (int i = 1; i < numberOfLevels; i++) { VoxelSideLengths[i] = VoxelSideLengths[i - 1] / voxelsPerSide[i]; } voxelDictionaryLevel0 = new VoxelBinSet(dimensions.Select(d => (int)Math.Ceiling(d / VoxelSideLengths[0])).ToArray(), bitLevelDistribution[0]); voxelsPerDimension = new int[NumberOfLevels][]; for (var i = 0; i < numberOfLevels; i++) { voxelsPerDimension[i] = dimensions.Select(d => (int)Math.Ceiling(d / VoxelSideLengths[i])).ToArray(); } var numChars0 = fileData.Voxels[0].Length; byte[] bytes = new byte[numChars0 / 2]; for (var i = 0; i < numChars0; i += 2) { bytes[i / 2] = Convert.ToByte(fileData.Voxels[0].Substring(i, 2), 16); } for (int i = 0; i < bytes.Length; i += 8) { var ID = BitConverter.ToInt64(bytes, i); Constants.GetAllFlags(ID, out var level, out VoxelRoleTypes role, out bool btmInside); voxelDictionaryLevel0.AddOrReplace(new VoxelBinClass(ID, role, this, btmInside)); } for (int i = 1; i < bitLevelDistribution.Length; i++) { var numChars = fileData.Voxels[i].Length; bytes = new byte[numChars / 2]; for (var k = 0; k < numChars; k += 2) { bytes[k / 2] = Convert.ToByte(fileData.Voxels[i].Substring(k, 2), 16); } for (int j = 0; j < bytes.Length; j += 8) { var ID = BitConverter.ToInt64(bytes, j); ((VoxelBinClass)voxelDictionaryLevel0.GetVoxel(ID)).InnerVoxels[i - 1] .AddOrReplace(ID); } } UpdateProperties(); if (fileData.Primitives != null && fileData.Primitives.Any()) { Primitives = fileData.Primitives; } }