forked from fogleman/simplify
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstl.go
103 lines (97 loc) · 2.43 KB
/
stl.go
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
package simplify
import (
"bufio"
"encoding/binary"
"os"
"strings"
)
type STLHeader struct {
_ [80]uint8
Count uint32
}
type STLTriangle struct {
N, V1, V2, V3 [3]float32
_ uint16
}
func LoadBinarySTL(path string) (*Mesh, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
header := STLHeader{}
if err := binary.Read(file, binary.LittleEndian, &header); err != nil {
return nil, err
}
count := int(header.Count)
triangles := make([]*Triangle, count)
for i := 0; i < count; i++ {
d := STLTriangle{}
if err := binary.Read(file, binary.LittleEndian, &d); err != nil {
return nil, err
}
v1 := Vector{float64(d.V1[0]), float64(d.V1[1]), float64(d.V1[2])}
v2 := Vector{float64(d.V2[0]), float64(d.V2[1]), float64(d.V2[2])}
v3 := Vector{float64(d.V3[0]), float64(d.V3[1]), float64(d.V3[2])}
triangles[i] = NewTriangle(v1, v2, v3)
}
return NewMesh(triangles), nil
}
func SaveBinarySTL(path string, mesh *Mesh) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
header := STLHeader{}
header.Count = uint32(len(mesh.Triangles))
if err := binary.Write(file, binary.LittleEndian, &header); err != nil {
return err
}
for _, triangle := range mesh.Triangles {
n := triangle.Normal()
d := STLTriangle{}
d.N[0] = float32(n.X)
d.N[1] = float32(n.Y)
d.N[2] = float32(n.Z)
d.V1[0] = float32(triangle.V1.X)
d.V1[1] = float32(triangle.V1.Y)
d.V1[2] = float32(triangle.V1.Z)
d.V2[0] = float32(triangle.V2.X)
d.V2[1] = float32(triangle.V2.Y)
d.V2[2] = float32(triangle.V2.Z)
d.V3[0] = float32(triangle.V3.X)
d.V3[1] = float32(triangle.V3.Y)
d.V3[2] = float32(triangle.V3.Z)
if err := binary.Write(file, binary.LittleEndian, &d); err != nil {
return err
}
}
return nil
}
func LoadSTL(path string) (*Mesh, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
var vertexes []Vector
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
fields := strings.Fields(line)
if len(fields) == 4 && fields[0] == "vertex" {
f := parseFloats(fields[1:])
v := Vector{f[0], f[1], f[2]}
vertexes = append(vertexes, v)
}
}
var triangles []*Triangle
for i := 0; i < len(vertexes); i += 3 {
v1 := vertexes[i+0]
v2 := vertexes[i+1]
v3 := vertexes[i+2]
triangles = append(triangles, NewTriangle(v1, v2, v3))
}
return NewMesh(triangles), scanner.Err()
}