This commit is contained in:
dqn
2024-06-06 02:26:04 +08:00
parent 4cf895656d
commit 6d0836d660
8 changed files with 326 additions and 283 deletions
+6 -10
View File
@@ -5,16 +5,12 @@ import (
)
func main() {
stl := stl2gltf.Load("D:\\src\\go\\stl2gltf\\example\\0c448109-7ac9-4f6d-aaf6-ce6bb744032f.stl")
// log.Println(stl)
stl2gltf.Convert(stl, "C:\\Users\\13040\\Downloads\\0c448109-7ac9-4f6d-aaf6-ce6bb744032f.gltf")
stl := stl2gltf.Load("./example/0c448109-7ac9-4f6d-aaf6-ce6bb744032f.stl")
stl2gltf.Convert(stl, "./example/0c448109-7ac9-4f6d-aaf6-ce6bb744032f.gltf")
// stl = stl2gltf.Load("D:\\src\\go\\stl2gltf\\example\\1ec91891-c25a-4905-a79c-f3bc96045d37.stl")
// // log.Println(stl)
// stl2gltf.Convert(stl, "C:\\Users\\13040\\Downloads\\1ec91891-c25a-4905-a79c-f3bc96045d37.gltf")
// stl = stl2gltf.Load("D:\\src\\go\\stl2gltf\\example\\3ea057e5-1520-4898-a59c-f33a6c955bd7.stl")
// // log.Println(stl)
// stl2gltf.Convert(stl, "C:\\Users\\13040\\Downloads\\3ea057e5-1520-4898-a59c-f33a6c955bd7.gltf")
stl = stl2gltf.Load("./example/1ec91891-c25a-4905-a79c-f3bc96045d37.stl")
stl2gltf.Convert(stl, "./example/1ec91891-c25a-4905-a79c-f3bc96045d37.gltf")
stl = stl2gltf.Load("./example/3ea057e5-1520-4898-a59c-f33a6c955bd7.stl")
stl2gltf.Convert(stl, "./example/3ea057e5-1520-4898-a59c-f33a6c955bd7.gltf")
}
+20 -21
View File
@@ -51,14 +51,14 @@ func Convert(stl STL, outFile string) {
allData := make([]byte, 0)
allData = append(allData, indexBuf...)
// allData = append(allData, normalBuf...)
allData = append(allData, normalBuf...)
allData = append(allData, positionBuf...)
base := base64.StdEncoding.EncodeToString(allData)
attributes := make(map[string]int, 0)
attributes["POSITION"] = 1
// attributes["NORMAL"] = 1
attributes["POSITION"] = 2
attributes["NORMAL"] = 1
gltf := GLTF{
Asset: Asset{Version: "2.0"},
@@ -75,17 +75,17 @@ func Convert(stl STL, outFile string) {
Target: 34963,
},
// normal
// {
// Buffer: 0,
// ByteOffset: len(indexBuf),
// ByteLength: len(normalBuf),
// Target: 34962,
// },
// position
{
Buffer: 0,
ByteOffset: len(indexBuf),
// ByteOffset: len(indexBuf) + len(normalBuf),
ByteLength: len(normalBuf),
Target: 34962,
},
// position
{
Buffer: 0,
// ByteOffset: len(indexBuf),
ByteOffset: len(indexBuf) + len(normalBuf),
ByteLength: len(positionBuf),
Target: 34962,
},
@@ -98,21 +98,20 @@ func Convert(stl STL, outFile string) {
Type: "SCALAR",
Count: stl.TriangleNum * 3,
},
// {
// BufferView: 1,
// ByteOffset: 0,
// ComponentType: 5126,
// Type: "VEC3",
// Count: int(stl.TriangleNum),
// // Max: []float32{1, 1, 1},
// // Min: []float32{-1, -1, -1},
// },
{
BufferView: 1,
ByteOffset: 0,
ComponentType: 5126,
Type: "VEC3",
Count: int(stl.TriangleNum),
Max: []float32{1, 1, 1},
Min: []float32{-1, -1, -1},
},
{
BufferView: 2,
ByteOffset: 0,
ComponentType: 5126,
Type: "VEC3",
Count: len(positionBuf) / 12,
Max: stl.Max,
Min: stl.Min,
-167
View File
@@ -1,167 +0,0 @@
package stl2gltf
import (
"encoding/base64"
"encoding/binary"
"encoding/json"
"fmt"
"log"
"os"
)
func Convert2(stl STL2, outFile string) {
// buf
indexBuf := make([]byte, 0)
normalBuf := make([]byte, 0)
positionBuf := make([]byte, 0)
padding := func(buf []byte) []byte {
log.Println("padding: ", len(buf)%4)
for len(buf)%4 != 0 {
log.Println("padding")
buf = append(buf, 0x00)
}
return buf
}
uniquePositions := make([][3]uint32, 0)
indices := make([]int16, len(stl.Positions))
for i := 0; i < len(stl.Positions); i++ {
position := stl.Positions[i]
// if in uniqt
found := false
for u, ut := range uniquePositions {
if ut[0] == position[0] && ut[1] == position[1] && ut[2] == position[2] {
// exist
indices[i] = int16(u)
found = true
}
}
if !found {
uniquePositions = append(uniquePositions, position)
indices[i] = int16(len(uniquePositions) - 1)
}
}
// 写入顶点
for _, ip := range uniquePositions {
buf := make([]byte, 0)
buf = binary.LittleEndian.AppendUint32(buf, uint32(ip[0]))
buf = binary.LittleEndian.AppendUint32(buf, uint32(ip[1]))
buf = binary.LittleEndian.AppendUint32(buf, uint32(ip[2]))
positionBuf = append(positionBuf, buf...)
}
positionBuf = padding(positionBuf)
// 写入法向量
// for i := range stl.TriangleNum {
// t := stl.Triangles[i]
// normalBuf = append(normalBuf, t.Normal...)
// normalBuf = append(normalBuf, t.Normal...)
// normalBuf = append(normalBuf, t.Normal...)
// }
normalBuf = padding(normalBuf)
// 写入索引
for i := range indices {
buf := make([]byte, 2)
binary.LittleEndian.PutUint16(buf, uint16(i))
indexBuf = append(indexBuf, buf...)
}
indexBuf = padding(indexBuf)
log.Println(len(positionBuf), len(normalBuf), len(indexBuf))
allData := make([]byte, 0)
allData = append(allData, positionBuf...)
allData = append(allData, indexBuf...)
// allData = append(allData, normalBuf...)
base := base64.StdEncoding.EncodeToString(allData)
attributes := make(map[string]int, 0)
attributes["POSITION"] = 0
// attributes["NORMAL"] = 1
gltf := GLTF{
Asset: Asset{Version: "2.0"},
Scenes: []Scene{{Nodes: []int{0}}},
Nodes: []Node{{Mesh: 0}},
Meshes: []Mesh{{Primitives: []Primitive{{Attributes: attributes, Indices: 1, Mode: 4}}}},
Buffers: []Buffer{{Uri: fmt.Sprintf("data:application/gltf-buffer;base64,%s", base), ByteLength: len(allData)}},
BufferViews: []BufferView{
// index
// normal
// {
// Buffer: 0,
// ByteOffset: len(indexBuf),
// ByteLength: len(normalBuf),
// Target: 34962,
// },
// position
{
Buffer: 0,
ByteOffset: 0,
// ByteOffset: len(indexBuf) + len(normalBuf),
ByteLength: len(positionBuf),
Target: 34962,
},
{
Buffer: 0,
ByteOffset: len(positionBuf),
ByteLength: len(indexBuf),
Target: 34963,
},
},
Accessors: []Accessor{
// {
// BufferView: 1,
// ByteOffset: 0,
// ComponentType: 5126,
// Type: "VEC3",
// Count: int(stl.TriangleNum),
// // Max: []float32{1, 1, 1},
// // Min: []float32{-1, -1, -1},
// },
{
BufferView: 0,
ByteOffset: 0,
ComponentType: 5126,
Type: "VEC3",
Count: len(positionBuf) / 12,
Max: f2i(stl.Max),
Min: f2i(stl.Min),
},
{
BufferView: 1,
ByteOffset: 0,
ComponentType: 5123,
Type: "SCALAR",
Count: stl.TriangleNum,
},
},
}
data, err := json.MarshalIndent(gltf, " ", " ")
if err != nil {
log.Println("marshal error: ", err.Error())
return
}
os.Remove(outFile)
f, err := os.OpenFile(outFile, os.O_CREATE, os.ModePerm)
if err != nil {
log.Println("write file error: ", err.Error())
return
}
defer f.Close()
f.Write(data)
}
func f2i(p []uint32) []float32 {
a := make([]float32, len(p))
for i := 0; i < len(p); i++ {
a[i] = float32(p[i])
}
return a
}
-17
View File
@@ -32,23 +32,6 @@ type STL struct {
Min []float32
}
type Triangle2 struct {
Normal []byte // 4 * 3 12
Position [][3]float32 // 4 * 3 * 3 36
Attribute []byte // 2 02
XYZ []float32
}
type STL2 struct {
Header string
TriangleNum int
Positions [][3]uint32
Max []uint32
Min []uint32
}
type Asset struct {
Version string `json:"version"`
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-68
View File
@@ -70,71 +70,3 @@ func Load(filePath string) (stl STL) {
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
}