-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from DomCR/Stl-reader
Stl reader
- Loading branch information
Showing
13 changed files
with
150,562 additions
and
11 deletions.
There are no files selected for viewing
Submodule CSUtilities
updated
3 files
+13 −0 | CSMath/VectorExtensions.cs | |
+11 −0 | CSMath/XYZ.cs | |
+49 −12 | CSUtilities/IO/StreamIO.cs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net5.0</TargetFramework> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" /> | ||
<PackageReference Include="xunit" Version="2.4.1" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="coverlet.collector" Version="3.1.0"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\MeshIO.STL\MeshIO.STL.csproj" /> | ||
<ProjectReference Include="..\MeshIO\MeshIO.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
using MeshIO.Core; | ||
using MeshIO.Elements; | ||
using MeshIO.Elements.Geometries; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace MeshIO.STL.Tests | ||
{ | ||
public class StlReaderTest | ||
{ | ||
private const string _samplesFolder = "../../../../samples/stl"; | ||
|
||
public static readonly TheoryData<string> AsciiFiles; | ||
|
||
public static readonly TheoryData<string> BinaryFiles; | ||
|
||
private readonly ITestOutputHelper _output; | ||
|
||
static StlReaderTest() | ||
{ | ||
AsciiFiles = new TheoryData<string>(); | ||
foreach (string file in Directory.GetFiles(_samplesFolder, "*_ascii.stl")) | ||
{ | ||
AsciiFiles.Add(file); | ||
} | ||
|
||
BinaryFiles = new TheoryData<string>(); | ||
foreach (string file in Directory.GetFiles(_samplesFolder, "*_binary.stl")) | ||
{ | ||
BinaryFiles.Add(file); | ||
} | ||
} | ||
|
||
public StlReaderTest(ITestOutputHelper output) | ||
{ | ||
this._output = output; | ||
} | ||
|
||
[Theory] | ||
[MemberData(nameof(BinaryFiles))] | ||
public void IsBinaryTest(string test) | ||
{ | ||
using (StlReader reader = new StlReader(test, onNotification)) | ||
{ | ||
Assert.True(reader.IsBinary()); | ||
} | ||
} | ||
|
||
[Theory] | ||
[MemberData(nameof(AsciiFiles))] | ||
public void IsAsciiTest(string test) | ||
{ | ||
using (StlReader reader = new StlReader(test, onNotification)) | ||
{ | ||
Assert.False(reader.IsBinary()); | ||
} | ||
} | ||
|
||
[Theory] | ||
[MemberData(nameof(AsciiFiles))] | ||
public void ReadAsciiTest(string test) | ||
{ | ||
this.readFile(test); | ||
} | ||
|
||
[Theory] | ||
[MemberData(nameof(BinaryFiles))] | ||
public void ReadBinaryTest(string test) | ||
{ | ||
this.readFile(test); | ||
} | ||
|
||
private Mesh readFile(string path) | ||
{ | ||
using (StlReader reader = new StlReader(path, onNotification)) | ||
{ | ||
return reader.Read(); | ||
} | ||
} | ||
|
||
private void onNotification(NotificationArgs e) | ||
{ | ||
this._output.WriteLine(e.Message); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,26 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net5.0</TargetFramework> | ||
<TargetFrameworks>net5.0;net48;netstandard2.1</TargetFrameworks> | ||
<LangVersion>9.0</LangVersion> | ||
<Authors>DomCr</Authors> | ||
<Company>MeshIO</Company> | ||
<Version>1.0.0</Version> | ||
<PackageId>MeshIO.STL</PackageId> | ||
<PackageTags>C# 3D fbx</PackageTags> | ||
<RepositoryUrl>/~https://github.com/DomCR/MeshIO</RepositoryUrl> | ||
<PackageLicenseExpression>MIT</PackageLicenseExpression> | ||
<RepositoryType>git</RepositoryType> | ||
<PackageProjectUrl>/~https://github.com/DomCR/MeshIO</PackageProjectUrl> | ||
<Copyright>Copyright (c) 2022 Albert Domenech</Copyright> | ||
<Description>MeshIO module for stl format.</Description> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\MeshIO\MeshIO.csproj" /> | ||
</ItemGroup> | ||
|
||
<Import Project="..\CSUtilities\CSUtilities\CSUtilities.projitems" Label="Shared" /> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System; | ||
|
||
namespace MeshIO.STL | ||
{ | ||
[Serializable] | ||
public class StlException : Exception | ||
{ | ||
public StlException(string message) : base(message) { } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,165 @@ | ||
namespace MeshIO.STL | ||
using CSMath; | ||
using CSUtilities.Converters; | ||
using CSUtilities.IO; | ||
using MeshIO.Core; | ||
using MeshIO.Elements.Geometries; | ||
using MeshIO.Elements.Geometries.Layers; | ||
using System; | ||
using System.IO; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace MeshIO.STL | ||
{ | ||
public class StlReader | ||
/// <summary> | ||
/// Reader for STL files in ascii or binary | ||
/// </summary> | ||
public class StlReader : ReaderBase, IDisposable | ||
{ | ||
private StreamIO _stream; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="StlReader"/> class for the specified file. | ||
/// </summary> | ||
/// <param name="path">The complete file path to read to.</param> | ||
/// <param name="onNotification"></param> | ||
public StlReader(string path, NotificationHandler onNotification = null) | ||
{ | ||
if (string.IsNullOrEmpty(path)) | ||
throw new ArgumentNullException(nameof(path)); | ||
|
||
this._stream = new StreamIO(path, FileMode.Open, FileAccess.Read); | ||
|
||
this.OnNotification = onNotification; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="FbxReader"/> class for the specified stream. | ||
/// </summary> | ||
/// <param name="stream">The stream to write to.</param> | ||
/// <param name="errorLevel"></param> | ||
public StlReader(Stream stream, NotificationHandler onNotification = null) | ||
{ | ||
if (stream == null) | ||
throw new ArgumentNullException(nameof(stream)); | ||
|
||
if (!stream.CanSeek) | ||
throw new ArgumentException("The stream must support seeking. Try reading the data into a buffer first"); | ||
|
||
this._stream = new StreamIO(stream); | ||
|
||
this.OnNotification = onNotification; | ||
} | ||
|
||
/// <summary> | ||
/// Check the format of the file | ||
/// </summary> | ||
/// <returns>true if is binary</returns> | ||
public bool IsBinary() | ||
{ | ||
this._stream.Position = 0; | ||
this._stream.ReadString(80); | ||
int nTriangles = this._stream.ReadInt<LittleEndianConverter>(); | ||
|
||
return checkStreamLenth(nTriangles); | ||
} | ||
|
||
/// <summary> | ||
/// Read the STL file | ||
/// </summary> | ||
/// <returns>mesh defined in the file</returns> | ||
public Mesh Read() | ||
{ | ||
this._stream.Position = 0; | ||
|
||
string header = this._stream.ReadString(80); | ||
this.OnNotification?.Invoke(new NotificationArgs(header.Replace("\0", ""))); | ||
|
||
Mesh mesh = new Mesh(); | ||
LayerElementNormal normals = new LayerElementNormal(); | ||
mesh.Layers.Add(normals); | ||
|
||
int nTriangles = this._stream.ReadInt<LittleEndianConverter>(); | ||
|
||
if (checkStreamLenth(nTriangles)) | ||
{ | ||
for (int i = 0; i < nTriangles; i++) | ||
{ | ||
XYZ normal = new XYZ(this._stream.ReadSingle(), this._stream.ReadSingle(), this._stream.ReadSingle()); | ||
|
||
normals.Add(normal); | ||
|
||
XYZ v1 = new XYZ(this._stream.ReadSingle(), this._stream.ReadSingle(), this._stream.ReadSingle()); | ||
XYZ v2 = new XYZ(this._stream.ReadSingle(), this._stream.ReadSingle(), this._stream.ReadSingle()); | ||
XYZ v3 = new XYZ(this._stream.ReadSingle(), this._stream.ReadSingle(), this._stream.ReadSingle()); | ||
|
||
mesh.AddTriangles(v1, v2, v3); | ||
|
||
ushort attByteCount = this._stream.ReadUShort(); | ||
} | ||
} | ||
else | ||
{ | ||
this._stream.Position = 0; | ||
|
||
string line = this._stream.ReadUntil('\n'); | ||
string name = Regex.Match(line, @"solid \s\n", options: RegexOptions.IgnoreCase).Value; | ||
mesh.Name = name; | ||
|
||
line = this._stream.ReadUntil('\n'); | ||
|
||
while (!line.Contains($"endsolid {name}")) | ||
{ | ||
XYZ normal = readPoint(line, "facet normal"); | ||
normals.Add(normal); | ||
|
||
this.checkLine(this._stream.ReadUntil('\n'), "outer loop"); | ||
|
||
XYZ v1 = readPoint(this._stream.ReadUntil('\n'), "vertex"); | ||
XYZ v2 = readPoint(this._stream.ReadUntil('\n'), "vertex"); | ||
XYZ v3 = readPoint(this._stream.ReadUntil('\n'), "vertex"); | ||
|
||
mesh.AddTriangles(v1, v2, v3); | ||
|
||
this.checkLine(this._stream.ReadUntil('\n'), "endloop"); | ||
this.checkLine(this._stream.ReadUntil('\n'), "endfacet"); | ||
|
||
line = this._stream.ReadUntil('\n'); | ||
} | ||
} | ||
|
||
return mesh; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public void Dispose() | ||
{ | ||
this._stream.Dispose(); | ||
} | ||
|
||
private bool checkStreamLenth(int nTriangles) | ||
{ | ||
//Compare the length of the stream to check if is ascii file | ||
return _stream.Length == 84 + nTriangles * 50; | ||
} | ||
|
||
private void checkLine(string line, string match) | ||
{ | ||
if (string.IsNullOrEmpty(match) && | ||
Regex.Match(line, match + @" \s\n", options: RegexOptions.IgnoreCase).Success) | ||
{ | ||
throw new StlException($"Expected match: {match} | line: {line}"); | ||
} | ||
} | ||
|
||
private XYZ readPoint(string line, string match) | ||
{ | ||
this.checkLine(line, match); | ||
|
||
var x = Regex.Match(line, @"\d+(\.\d+)?"); | ||
var y = x.NextMatch(); | ||
var z = y.NextMatch(); | ||
|
||
return new XYZ(double.Parse(x.Value), double.Parse(y.Value), double.Parse(z.Value)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace MeshIO.STL | ||
{ | ||
public class StlWriter | ||
{ | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.