-
Notifications
You must be signed in to change notification settings - Fork 2
/
StandardMesh.cs
117 lines (109 loc) · 4.03 KB
/
StandardMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Stl2Blueprint
{
public class StandardMesh : Mesh
{
public Triangle[] Triangles { get; }
public Line [] Edges { get; }
public Vector3[] Verticies { get; }
public BoundingBox Bounds { get; }
public StandardMesh(IEnumerable<Triangle> triangles, IEnumerable<Line> edges, IEnumerable<Vector3> verticies,
Vector3 min, Vector3 max)
{
Triangles = triangles.ToArray();
Edges = edges.ToArray();
Verticies = verticies.ToArray();
Bounds = new BoundingBox(min, max);
}
public static StandardMesh ParseStl(string fileName)
{
List<Triangle> triangles = new List<Triangle>();
HashSet<Line> edges = new HashSet<Line>();
HashSet<Vector3> verticies = new HashSet<Vector3>();
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
BinaryReader br = new BinaryReader(File.OpenRead(fileName));
ASCIIEncoding ascii = new ASCIIEncoding();
string header = ascii.GetString(br.ReadBytes(80));
int errors = 0;
int total = 0;
if (header.StartsWith("solid"))
{
br.Close();
StreamReader sr = new StreamReader(File.OpenRead(fileName), ascii);
while (Triangle.ReadFindAscii(sr, out string triangleLine))
{
if (Triangle.ReadAscii(sr, triangleLine, out Triangle t))
{
min = Vector3.Min(min, t.aabb.min);
max = Vector3.Max(max, t.aabb.max);
triangles.Add(t);
edges.Add(t.edge12);
edges.Add(t.edge31);
edges.Add(t.edge23);
verticies.Add(t.vertex1);
verticies.Add(t.vertex2);
verticies.Add(t.vertex3);
}
else
{
errors++;
}
total++;
}
sr.Close();
}
else
{
uint count = br.ReadUInt32();
total = (int)count;
for (uint i = 0; i < count; i++)
{
if(Triangle.ReadBinary(br, out Triangle t))
{
min = Vector3.Min(min, t.aabb.min);
max = Vector3.Max(max, t.aabb.max);
triangles.Add(t);
edges.Add(t.edge12);
edges.Add(t.edge31);
edges.Add(t.edge23);
verticies.Add(t.vertex1);
verticies.Add(t.vertex2);
verticies.Add(t.vertex3);
}
else
{
errors++;
}
}
br.Close();
}
if (errors / (float)total > GlobalConstants.meshErrorThreshold)
MessageBox.Show(errors + " invalid triangles were ignored in the stl file.");
return new StandardMesh(triangles, edges, verticies, min, max);
}
public bool ContainsPoint (Vector3 p)
{
int count = 0;
for(int i = 0; i < Triangles.Length; i++)
{
if (Triangles[i].IntersectsPoint(p))
count++;
}
return count % 2 == 1;
}
public bool IntersectsBox(BoundingBox box)
{
foreach(Triangle t in Triangles)
{
if (t.IntersectsBox(box))
return true;
}
return false;
}
}
}