141 lines
3.0 KiB
Go
141 lines
3.0 KiB
Go
package stl2gltf
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"log"
|
|
"math"
|
|
"os"
|
|
)
|
|
|
|
func Load(filePath string) (stl STL) {
|
|
file, err := os.OpenFile(filePath, os.O_RDONLY, os.ModePerm)
|
|
if err != nil {
|
|
log.Panic("open file " + filePath + " error: " + err.Error())
|
|
}
|
|
headerBuf := make([]byte, 80)
|
|
file.Read(headerBuf)
|
|
triangleNumBuf := make([]byte, 4)
|
|
file.Read(triangleNumBuf)
|
|
|
|
stl.Header = string(headerBuf)
|
|
stl.TriangleNum = int(binary.LittleEndian.Uint32(triangleNumBuf))
|
|
|
|
stl.Triangles = make([]Triangle, 0)
|
|
|
|
max := []float32{0, 0, 0}
|
|
min := []float32{0, 0, 0}
|
|
for range stl.TriangleNum {
|
|
normalBuf := make([]byte, 4*3)
|
|
file.Read(normalBuf)
|
|
|
|
positionBuf := make([]byte, 4*3*3)
|
|
file.Read(positionBuf)
|
|
|
|
for r := range 3 {
|
|
x := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[:4+(r*4)]))
|
|
y := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[(r * 4) : (r*4)+4]))
|
|
z := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[(r*4)+4 : (r*4)+8]))
|
|
if max[0] < x {
|
|
max[0] = x
|
|
}
|
|
if max[1] < y {
|
|
max[1] = y
|
|
}
|
|
if max[2] < z {
|
|
max[2] = z
|
|
}
|
|
if min[0] > x {
|
|
min[0] = x
|
|
}
|
|
if min[1] > y {
|
|
min[1] = y
|
|
}
|
|
if min[2] > z {
|
|
min[2] = z
|
|
}
|
|
}
|
|
|
|
attributeBuf := make([]byte, 2)
|
|
file.Read(attributeBuf)
|
|
|
|
stl.Triangles = append(stl.Triangles, Triangle{
|
|
Normal: normalBuf,
|
|
Position: positionBuf,
|
|
Attribute: attributeBuf,
|
|
})
|
|
}
|
|
|
|
stl.Max = max
|
|
stl.Min = min
|
|
|
|
return stl
|
|
}
|
|
|
|
func Load2(filePath string) (stl STL2) {
|
|
file, err := os.OpenFile(filePath, os.O_RDONLY, os.ModePerm)
|
|
if err != nil {
|
|
log.Panic("open file " + filePath + " error: " + err.Error())
|
|
}
|
|
headerBuf := make([]byte, 80)
|
|
file.Read(headerBuf)
|
|
triangleNumBuf := make([]byte, 4)
|
|
file.Read(triangleNumBuf)
|
|
|
|
stl.Header = string(headerBuf)
|
|
stl.TriangleNum = int(binary.LittleEndian.Uint32(triangleNumBuf))
|
|
|
|
stl.Positions = make([][3]uint32, 0)
|
|
|
|
max := []uint32{0, 0, 0}
|
|
min := []uint32{0, 0, 0}
|
|
for range stl.TriangleNum {
|
|
normalBuf := make([]byte, 4*3)
|
|
file.Read(normalBuf)
|
|
|
|
positionBuf := make([]byte, 4*3*3)
|
|
file.Read(positionBuf)
|
|
x := uint32(0)
|
|
y := uint32(0)
|
|
z := uint32(0)
|
|
for r := range 3 {
|
|
x1 := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[:4+(r*4)]))
|
|
y1 := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[(r * 4) : (r*4)+4]))
|
|
z1 := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[(r*4)+4 : (r*4)+8]))
|
|
|
|
// x = uint32(x1) * 10000 / 10000
|
|
// y = uint32(y1) * 10000 / 10000
|
|
// z = uint32(z1) * 10000 / 10000
|
|
x = uint32(x1) * 1 / 1
|
|
y = uint32(y1) * 1 / 1
|
|
z = uint32(z1) * 1 / 1
|
|
|
|
if max[0] < x {
|
|
max[0] = x
|
|
}
|
|
if max[1] < y {
|
|
max[1] = y
|
|
}
|
|
if max[2] < z {
|
|
max[2] = z
|
|
}
|
|
if min[0] > x {
|
|
min[0] = x
|
|
}
|
|
if min[1] > y {
|
|
min[1] = y
|
|
}
|
|
if min[2] > z {
|
|
min[2] = z
|
|
}
|
|
stl.Positions = append(stl.Positions, [3]uint32{x, y, z})
|
|
}
|
|
attributeBuf := make([]byte, 2)
|
|
file.Read(attributeBuf)
|
|
}
|
|
|
|
stl.Max = max
|
|
stl.Min = min
|
|
|
|
return stl
|
|
}
|