-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
remove_unreferenced_vertices.go
71 lines (59 loc) · 2.23 KB
/
remove_unreferenced_vertices.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
package meshops
import (
"github.com/EliCDavis/iter"
"github.com/EliCDavis/polyform/modeling"
"github.com/EliCDavis/vector/vector2"
"github.com/EliCDavis/vector/vector3"
"github.com/EliCDavis/vector/vector4"
)
type RemovedUnreferencedVerticesTransformer struct{}
func (fnt RemovedUnreferencedVerticesTransformer) Transform(m modeling.Mesh) (results modeling.Mesh, err error) {
return RemovedUnreferencedVertices(m), nil
}
func removedUnreferenced[T any](used []bool, attributes []string, retriever func(string) *iter.ArrayIterator[T]) map[string][]T {
finalData := make(map[string][]T)
for _, attribute := range attributes {
data := retriever(attribute)
finalAtrVals := make([]T, 0)
for i := 0; i < data.Len(); i++ {
if used[i] {
finalAtrVals = append(finalAtrVals, data.At(i))
}
}
if len(finalAtrVals) == 0 {
continue
}
finalData[attribute] = finalAtrVals
}
return finalData
}
func RemovedUnreferencedVertices(m modeling.Mesh) modeling.Mesh {
originalIndices := m.Indices()
used := make([]bool, m.AttributeLength())
for i := 0; i < originalIndices.Len(); i++ {
used[originalIndices.At(i)] = true
}
shiftBy := make([]int, m.AttributeLength())
skipped := 0
for i := range shiftBy {
if !used[i] {
skipped++
}
shiftBy[i] = skipped
}
finalV4Data := removedUnreferenced(used, m.Float4Attributes(), func(s string) *iter.ArrayIterator[vector4.Float64] { return m.Float4Attribute(s) })
finalV3Data := removedUnreferenced(used, m.Float3Attributes(), func(s string) *iter.ArrayIterator[vector3.Float64] { return m.Float3Attribute(s) })
finalV2Data := removedUnreferenced(used, m.Float2Attributes(), func(s string) *iter.ArrayIterator[vector2.Float64] { return m.Float2Attribute(s) })
finalV1Data := removedUnreferenced(used, m.Float1Attributes(), func(s string) *iter.ArrayIterator[float64] { return m.Float1Attribute(s) })
finalIndices := make([]int, originalIndices.Len())
for triI := 0; triI < len(finalIndices); triI++ {
finalIndices[triI] = originalIndices.At(triI) - shiftBy[originalIndices.At(triI)]
}
return modeling.
NewMesh(m.Topology(), finalIndices).
SetFloat4Data(finalV4Data).
SetFloat3Data(finalV3Data).
SetFloat2Data(finalV2Data).
SetFloat1Data(finalV1Data).
SetMaterials(m.Materials())
}