changeset 678:7bb961d750b6 octree

octree: traverse horizontally over tree to find out which triangles to process.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 19 Sep 2018 17:34:19 +0200
parents 1cb565d244cf
children 899116318d58
files cmd/octree2contour/loader.go cmd/octree2contour/main.go cmd/tin2octree/builder.go
diffstat 3 files changed, 73 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/cmd/octree2contour/loader.go	Wed Sep 19 15:37:37 2018 +0200
+++ b/cmd/octree2contour/loader.go	Wed Sep 19 17:34:19 2018 +0200
@@ -52,6 +52,8 @@
 		return nil, err
 	}
 
+	log.Printf("EPSG: %d\n", tree.epsg)
+
 	if err := tree.min.read(r); err != nil {
 		return nil, err
 	}
@@ -60,6 +62,10 @@
 		return nil, err
 	}
 
+	log.Printf("BBOX: [[%f, %f, %f], [%f, %f, %f]]\n",
+		tree.min.x, tree.min.y, tree.min.z,
+		tree.max.x, tree.max.y, tree.max.z)
+
 	var numVertices uint32
 	if err := binary.Read(r, binary.LittleEndian, &numVertices); err != nil {
 		return nil, err
@@ -128,6 +134,64 @@
 	return tree, nil
 }
 
+func (ot *octree) horizontal(h float64, fn func([]int32)) {
+
+	type frame struct {
+		pos int32
+		min float64
+		max float64
+	}
+
+	if h < ot.min.z || h > ot.max.z {
+		return
+	}
+
+	stack := []frame{{1, ot.min.z, ot.max.z}}
+
+	for len(stack) > 0 {
+		top := stack[len(stack)-1]
+		stack = stack[:len(stack)-1]
+
+		pos, min, max := top.pos, top.min, top.max
+		if pos == 0 {
+			continue
+		}
+
+		if pos > 0 { // node
+			if mid := (max-min)*0.5 + min; h <= mid {
+				stack = append(stack,
+					frame{ot.index[pos+0], min, mid},
+					frame{ot.index[pos+1], min, mid},
+					frame{ot.index[pos+4], min, mid},
+					frame{ot.index[pos+5], min, mid})
+			} else {
+				stack = append(stack,
+					frame{ot.index[pos+2], mid, max},
+					frame{ot.index[pos+3], mid, max},
+					frame{ot.index[pos+6], mid, max},
+					frame{ot.index[pos+7], mid, max})
+			}
+		} else { // leaf
+			pos = -pos - 1
+			n := ot.index[pos]
+			//log.Printf("%d %d %d\n", pos, n, len(ot.index))
+			indices := ot.index[pos+1 : pos+1+n]
+
+			for idx := range indices {
+				tri := ot.triangles[idx]
+				v0 := ot.vertices[tri[0]]
+				v1 := ot.vertices[tri[1]]
+				v2 := ot.vertices[tri[2]]
+
+				if !(math.Min(v0.z, math.Min(v1.z, v2.z)) > h ||
+					math.Max(v0.z, math.Max(v1.z, v2.z)) < h) {
+					fn(tri)
+				}
+			}
+		}
+	}
+}
+
 func loadOctree(fname string) (*octree, error) {
 
 	f, err := os.Open(fname)
--- a/cmd/octree2contour/main.go	Wed Sep 19 15:37:37 2018 +0200
+++ b/cmd/octree2contour/main.go	Wed Sep 19 17:34:19 2018 +0200
@@ -13,7 +13,14 @@
 )
 
 func process(tree *octree) {
-	// TODO: Implement me!
+	if *one {
+		var triangles int
+		tree.horizontal(*step, func([]int32) {
+			triangles++
+		})
+		log.Printf("num triangles: %d\n", triangles)
+	} else {
+	}
 }
 
 func main() {
--- a/cmd/tin2octree/builder.go	Wed Sep 19 15:37:37 2018 +0200
+++ b/cmd/tin2octree/builder.go	Wed Sep 19 17:34:19 2018 +0200
@@ -48,7 +48,7 @@
 ) int32 {
 	if len(triangles) <= 16 || depth > 8 {
 		pos := len(tb.index)
-		tb.index = append(tb.index, int32(len(tb.index)))
+		tb.index = append(tb.index, int32(len(triangles)))
 		tb.index = append(tb.index, triangles...)
 		//log.Printf("leaf entries: %d (%d)\n", len(triangles), depth)
 		tb.leaves++