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]],