Mercurial > gemma
diff pkg/octree/strtree.go @ 2516:1ec4c5633eb6 octree-diff
Clip STR tree and not Octree.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 05 Mar 2019 17:08:16 +0100 |
parents | 6bcaa8bf2603 |
children | e26000628764 |
line wrap: on
line diff
--- a/pkg/octree/strtree.go Tue Mar 05 15:55:14 2019 +0100 +++ b/pkg/octree/strtree.go Tue Mar 05 17:08:16 2019 +0100 @@ -21,19 +21,16 @@ const numEntries = 8 type STRTree struct { - tri *Triangulation - index []int32 - triangles [][]int32 - bboxes []Box2D + tin *Tin + index []int32 + bboxes []Box2D } -func (s *STRTree) Build(t *Triangulation) { - - s.tri = t +func (s *STRTree) Build(t *Tin) { - s.triangles = t.TriangleSlices() + s.tin = t - all := make([]int32, len(s.triangles)) + all := make([]int32, len(t.Triangles)) for i := range all { all[i] = int32(i) @@ -46,11 +43,63 @@ s.index[0] = root } +func (s *STRTree) Clip(p *Polygon) map[int32]struct{} { + + removed := make(map[int32]struct{}) + + stack := []int32{s.index[0]} + + for len(stack) > 0 { + top := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + if top > 0 { // node + switch p.IntersectionBox2D(s.bbox(top)) { + case IntersectionInside: + // all triangles are inside polygon + case IntersectionOutSide: + // all triangles are outside polygon + s.allTriangles(top, removed) + default: + // mixed bag + for i, n := int32(0), s.index[top+1]; i < n; i++ { + stack = append(stack, s.index[top+2+i]) + } + } + } else { // leaf + top = -top - 1 + for i, n := int32(0), s.index[top+1]; i < n; i++ { + removed[s.index[top+2+i]] = struct{}{} + } + } + } + + return removed +} + +func (s *STRTree) allTriangles(pos int32, tris map[int32]struct{}) { + stack := []int32{pos} + for len(stack) > 0 { + top := stack[len(stack)-1] + stack = stack[:len(stack)-1] + if top > 0 { // node + for i, n := int32(0), s.index[top+1]; i < n; i++ { + stack = append(stack, s.index[top+2+i]) + } + } else { // leaf + top = -top - 1 + for i, n := int32(0), s.index[top+1]; i < n; i++ { + tris[s.index[top+2+i]] = struct{}{} + } + } + } +} + func (s *STRTree) build(items []int32) int32 { sort.Slice(items, func(i, j int) bool { - ti := s.triangles[items[i]] - tj := s.triangles[items[j]] - return s.tri.Points[ti[0]].X < s.tri.Points[tj[0]].X + ti := s.tin.Triangles[items[i]] + tj := s.tin.Triangles[items[j]] + return s.tin.Vertices[ti[0]].X < s.tin.Vertices[tj[0]].X }) P := int(math.Ceil(float64(len(items)) / float64(numEntries))) @@ -75,9 +124,9 @@ for _, slice := range slices { sort.Slice(slice, func(i, j int) bool { - ti := s.triangles[slice[i]] - tj := s.triangles[slice[j]] - return s.tri.Points[ti[0]].Y < s.tri.Points[tj[0]].Y + ti := s.tin.Triangles[slice[i]] + tj := s.tin.Triangles[slice[j]] + return s.tin.Vertices[ti[0]].Y < s.tin.Vertices[tj[0]].Y }) for len(slice) > 0 { @@ -174,8 +223,8 @@ s.index = append(s.index, 0, int32(len(items))) s.index = append(s.index, items...) if len(items) > 0 { - vertices := s.tri.Points - ti := s.triangles[items[0]] + vertices := s.tin.Vertices + ti := s.tin.Triangles[items[0]] t := Triangle{ vertices[ti[0]], vertices[ti[1]], @@ -184,7 +233,7 @@ box := t.BBox() for i := 1; i < len(items); i++ { it := items[i] - ti := s.triangles[it] + ti := s.tin.Triangles[it] t := Triangle{ vertices[ti[0]], vertices[ti[1]],