Skip to content

Commit

Permalink
improve ascii/binary detection
Browse files Browse the repository at this point in the history
  • Loading branch information
brettfo committed Sep 13, 2023
1 parent 93855a7 commit 7602b74
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 9 deletions.
68 changes: 68 additions & 0 deletions src/IxMilia.Stl.Test/StlReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,74 @@ public void ReadBinaryStlNoLengthOrPositionStreamTest()
Assert.Equal(new StlVertex(22.0f, 23.0f, 24.0f), file.Triangles[1].Vertex3);
}

[Fact]
public void ReadBinaryStlWithAsciiHeaderTest()
{
var binarySize =
80 + // header
sizeof(int) + // number of triangles
2 * // 2 verticies
(
sizeof(float) * 3 + // normal vector
sizeof(float) * 3 + // vertex 1
sizeof(float) * 3 + // vertex 2
sizeof(float) * 3 + // vertex 3
sizeof(short) // attribute byte count
);
var binaryList = new List<byte>();

var headerText = "solid TestSolid";
binaryList.AddRange(Encoding.ASCII.GetBytes(headerText));
binaryList.AddRange(new byte[80 - headerText.Length]); // header
binaryList.AddRange(BitConverter.GetBytes(2)); // 2 triangles

// first triangle
binaryList.AddRange(BitConverter.GetBytes(1.0f)); // normal.X
binaryList.AddRange(BitConverter.GetBytes(2.0f)); // normal.Y
binaryList.AddRange(BitConverter.GetBytes(3.0f)); // normal.Z
binaryList.AddRange(BitConverter.GetBytes(4.0f)); // vertex1.X
binaryList.AddRange(BitConverter.GetBytes(5.0f)); // vertex1.Y
binaryList.AddRange(BitConverter.GetBytes(6.0f)); // vertex1.Z
binaryList.AddRange(BitConverter.GetBytes(7.0f)); // vertex2.X
binaryList.AddRange(BitConverter.GetBytes(8.0f)); // vertex2.Y
binaryList.AddRange(BitConverter.GetBytes(9.0f)); // vertex2.Z
binaryList.AddRange(BitConverter.GetBytes(10.0f)); // vertex3.X
binaryList.AddRange(BitConverter.GetBytes(11.0f)); // vertex3.Y
binaryList.AddRange(BitConverter.GetBytes(12.0f)); // vertex3.Z
binaryList.AddRange(BitConverter.GetBytes((short)0)); // attribute byte count

// second triangle
binaryList.AddRange(BitConverter.GetBytes(13.0f)); // normal.X
binaryList.AddRange(BitConverter.GetBytes(14.0f)); // normal.Y
binaryList.AddRange(BitConverter.GetBytes(15.0f)); // normal.Z
binaryList.AddRange(BitConverter.GetBytes(16.0f)); // vertex1.X
binaryList.AddRange(BitConverter.GetBytes(17.0f)); // vertex1.Y
binaryList.AddRange(BitConverter.GetBytes(18.0f)); // vertex1.Z
binaryList.AddRange(BitConverter.GetBytes(19.0f)); // vertex2.X
binaryList.AddRange(BitConverter.GetBytes(20.0f)); // vertex2.Y
binaryList.AddRange(BitConverter.GetBytes(21.0f)); // vertex2.Z
binaryList.AddRange(BitConverter.GetBytes(22.0f)); // vertex3.X
binaryList.AddRange(BitConverter.GetBytes(23.0f)); // vertex3.Y
binaryList.AddRange(BitConverter.GetBytes(24.0f)); // vertex3.Z
binaryList.AddRange(BitConverter.GetBytes((short)0)); // attribute byte count

Assert.Equal(binarySize, binaryList.Count);

var file = FromBytes(binaryList.ToArray());
Assert.Equal("TestSolid", file.SolidName);
Assert.Equal(2, file.Triangles.Count);

Assert.Equal(new StlNormal(1.0f, 2.0f, 3.0f), file.Triangles[0].Normal);
Assert.Equal(new StlVertex(4.0f, 5.0f, 6.0f), file.Triangles[0].Vertex1);
Assert.Equal(new StlVertex(7.0f, 8.0f, 9.0f), file.Triangles[0].Vertex2);
Assert.Equal(new StlVertex(10.0f, 11.0f, 12.0f), file.Triangles[0].Vertex3);

Assert.Equal(new StlNormal(13.0f, 14.0f, 15.0f), file.Triangles[1].Normal);
Assert.Equal(new StlVertex(16.0f, 17.0f, 18.0f), file.Triangles[1].Vertex1);
Assert.Equal(new StlVertex(19.0f, 20.0f, 21.0f), file.Triangles[1].Vertex2);
Assert.Equal(new StlVertex(22.0f, 23.0f, 24.0f), file.Triangles[1].Vertex3);
}

[Fact]
public void ReadAsciiTriangleWithNoNormalTest()
{
Expand Down
16 changes: 7 additions & 9 deletions src/IxMilia.Stl/StlReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,19 @@ public StlReader(Stream stream)
public string ReadSolidName()
{
int i;
bool headerComplete = false;
bool headerAsciiComplete = false;
bool headerBinaryComplete = false;
var sb = new StringBuilder();
for (i = 0; i < 80 && !headerComplete; i++)
for (i = 0; i < 80 && !headerAsciiComplete && !headerBinaryComplete; i++)
{
var b = binReader.ReadByte();
if (b == '\n')
{
headerComplete = true;
headerAsciiComplete = true;
}
else if (b == 0)
{
headerComplete = true;
headerBinaryComplete = true;
}
else
{
Expand All @@ -47,13 +48,10 @@ public string ReadSolidName()
var match = headerReg.Match(header);
if (match.Success)
{
isAscii = true;
header = match.Groups[1].Value;
}
else
{
isAscii = false;
}

isAscii = headerAsciiComplete && match.Success;

if (isAscii)
{
Expand Down

0 comments on commit 7602b74

Please sign in to comment.