forked from markus-wa/quickhull-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhalf_edge_mesh.go
88 lines (71 loc) · 2.37 KB
/
half_edge_mesh.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
package quickhull
import (
"github.com/golang/geo/r3"
)
// HalfEdgeMesh is a mesh consisting of half edges.
// See: https://www.openmesh.org/media/Documentations/OpenMesh-6.3-Documentation/a00010.html
type HalfEdgeMesh struct {
Vertices []r3.Vector
Faces []Face
HalfEdges []HalfEdge
}
// HalfEdge is a half edge.
// See: https://www.openmesh.org/media/Documentations/OpenMesh-6.3-Documentation/a00010.html
type HalfEdge struct {
EndVertex int // Index of end vertex
Opp int // Index of opposite HalfEdge
Face int // Index of Face it belongs to
Next int // Index of next HalfEdge
}
const disabledInt = ^int(0)
func (he *HalfEdge) disable() {
he.EndVertex = disabledInt
}
func (he HalfEdge) isDisabled() bool {
return he.EndVertex == disabledInt
}
// Face of a half edge.
// See: https://www.openmesh.org/media/Documentations/OpenMesh-6.3-Documentation/a00010.html
type Face struct {
HalfEdge int // Index of a bounding HalfEdge
}
func newHalfEdgeMesh(builder meshBuilder, vertices []r3.Vector) HalfEdgeMesh {
var heMesh HalfEdgeMesh
faceMapping := make(map[int]int)
halfEdgeMapping := make(map[int]int)
vertexMapping := make(map[int]int)
for i, f := range builder.faces {
if f.isDisabled() {
continue
}
heMesh.Faces = append(heMesh.Faces, Face{HalfEdge: f.halfEdgeIndex})
faceMapping[i] = len(heMesh.Faces) - 1
heIndicies := builder.halfEdgeIndicesOfFace(f)
for _, heIndex := range heIndicies {
vertexIndex := builder.halfEdges[heIndex].EndVertex
if _, contains := vertexMapping[vertexIndex]; !contains {
heMesh.Vertices = append(heMesh.Vertices, vertices[vertexIndex])
vertexMapping[vertexIndex] = len(heMesh.Vertices) - 1
}
}
}
for i, he := range builder.halfEdges {
if he.isDisabled() {
continue
}
heMesh.HalfEdges = append(heMesh.HalfEdges, he)
halfEdgeMapping[i] = len(heMesh.HalfEdges) - 1
}
for i := range heMesh.Faces {
_, contains := halfEdgeMapping[heMesh.Faces[i].HalfEdge]
assertTrue(contains)
heMesh.Faces[i].HalfEdge = halfEdgeMapping[heMesh.Faces[i].HalfEdge]
}
for i := range heMesh.HalfEdges {
heMesh.HalfEdges[i].Face = faceMapping[heMesh.HalfEdges[i].Face]
heMesh.HalfEdges[i].Opp = halfEdgeMapping[heMesh.HalfEdges[i].Opp]
heMesh.HalfEdges[i].Next = halfEdgeMapping[heMesh.HalfEdges[i].Next]
heMesh.HalfEdges[i].EndVertex = vertexMapping[heMesh.HalfEdges[i].EndVertex]
}
return heMesh
}