comparison cmd/octree2contour/loader.go @ 707:9db4ae29ded9 octree

octree: Moved octree traveral code to own file.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 21 Sep 2018 11:02:24 +0200
parents be90ab542aa7
children 5af9ab39e715
comparison
equal deleted inserted replaced
704:fe0889460e97 707:9db4ae29ded9
8 "math" 8 "math"
9 "os" 9 "os"
10 10
11 "github.com/golang/snappy" 11 "github.com/golang/snappy"
12 ) 12 )
13
14 type octree struct {
15 epsg uint32
16
17 vertices []vertex
18 triangles [][]int32
19 index []int32
20
21 min vertex
22 max vertex
23 }
24 13
25 func (v *vertex) read(r io.Reader) error { 14 func (v *vertex) read(r io.Reader) error {
26 var buf [8]byte 15 var buf [8]byte
27 b := buf[:] 16 b := buf[:]
28 if _, err := io.ReadFull(r, b); err != nil { 17 if _, err := io.ReadFull(r, b); err != nil {
127 } 116 }
128 117
129 return tree, nil 118 return tree, nil
130 } 119 }
131 120
132 func (ot *octree) horizontal(h float64, fn func(*triangle)) {
133
134 type frame struct {
135 pos int32
136 min float64
137 max float64
138 }
139
140 if h < ot.min.z || ot.max.z < h {
141 return
142 }
143
144 stack := []frame{{1, ot.min.z, ot.max.z}}
145
146 dupes := map[int32]struct{}{}
147
148 for len(stack) > 0 {
149 top := stack[len(stack)-1]
150 stack = stack[:len(stack)-1]
151
152 pos := top.pos
153 if pos == 0 {
154 continue
155 }
156 min, max := top.min, top.max
157
158 if pos > 0 { // node
159 if mid := (max-min)*0.5 + min; h >= mid {
160 pos += 4 // nodes with z-bit set
161 min = mid
162 } else {
163 max = mid
164 }
165 stack = append(stack,
166 frame{ot.index[pos+0], min, max},
167 frame{ot.index[pos+1], min, max},
168 frame{ot.index[pos+2], min, max},
169 frame{ot.index[pos+3], min, max})
170 } else { // leaf
171 pos = -pos - 1
172 n := ot.index[pos]
173 //log.Printf("%d %d %d\n", pos, n, len(ot.index))
174 indices := ot.index[pos+1 : pos+1+n]
175
176 for _, idx := range indices {
177 if _, found := dupes[idx]; found {
178 continue
179 }
180 tri := ot.triangles[idx]
181 t := triangle{
182 ot.vertices[tri[0]],
183 ot.vertices[tri[1]],
184 ot.vertices[tri[2]],
185 }
186
187 if !(math.Min(t[0].z, math.Min(t[1].z, t[2].z)) > h ||
188 math.Max(t[0].z, math.Max(t[1].z, t[2].z)) < h) {
189 dupes[idx] = struct{}{}
190 fn(&t)
191 }
192 }
193 }
194 }
195 }
196
197 func loadOctree(fname string) (*octree, error) { 121 func loadOctree(fname string) (*octree, error) {
198 122
199 f, err := os.Open(fname) 123 f, err := os.Open(fname)
200 if err != nil { 124 if err != nil {
201 return nil, err 125 return nil, err