changeset 5680:a87900c0fd11 sr-v2

Remove triangles that are not registered in the spatial index.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 11 Feb 2024 18:40:37 +0100
parents 03dfbe675842
children c09d55e9f098
files pkg/mesh/meshserialize.go pkg/mesh/meshserialize_v2.go pkg/mesh/strtree.go
diffstat 3 files changed, 70 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/mesh/meshserialize.go	Sun Feb 11 12:37:09 2024 +0100
+++ b/pkg/mesh/meshserialize.go	Sun Feb 11 18:40:37 2024 +0100
@@ -36,8 +36,9 @@
 
 func (s *STRTree) OptimizeForSerialization(version int) {
 	version = coalesceVersion(version)
-	// TODO: Implement me!
-	_ = version
+	if version == 2 {
+		s.optimizeForSerializationV2()
+	}
 }
 
 // Bytes serializes this tree to a byte slice.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/mesh/meshserialize_v2.go	Sun Feb 11 18:40:37 2024 +0100
@@ -0,0 +1,50 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2024 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package mesh
+
+func (s *STRTree) optimizeForSerializationV2() {
+	s.removeUnusedTriangles()
+	// TODO: Implement me!
+}
+
+// removeUnusedTriangles removes all triangles from the
+// TIN that are not registered in the spatial index.
+func (s *STRTree) removeUnusedTriangles() {
+	used := make([]bool, len(s.tin.Triangles))
+	unused := len(used)
+	s.allTriangleIndices(func(indices []int32) {
+		for _, idx := range indices {
+			used[idx] = true
+			unused-- // They only occur once in the spatial index.
+		}
+	})
+	if unused <= 0 {
+		return
+	}
+	newTris := make([][]int32, 0, len(s.tin.Triangles)-unused)
+	remap := map[int32]int32{}
+	for idx, tri := range s.tin.Triangles {
+		if used[idx] {
+			remap[int32(idx)] = int32(len(newTris))
+			newTris = append(newTris, tri)
+		}
+	}
+	s.tin.Triangles = newTris
+	// Update the spatial index as the gaps are now closed.
+	s.allTriangleIndices(func(indices []int32) {
+		for i, idx := range indices {
+			indices[i] = remap[idx]
+		}
+	})
+}
--- a/pkg/mesh/strtree.go	Sun Feb 11 12:37:09 2024 +0100
+++ b/pkg/mesh/strtree.go	Sun Feb 11 18:40:37 2024 +0100
@@ -409,3 +409,20 @@
 	}
 	return int32(-(pos + 1))
 }
+
+// allTriangleIndices passes all triangle indices to callback fn.
+func (s *STRTree) allTriangleIndices(fn func([]int32)) {
+	stack := []int32{s.index[0]}
+	for len(stack) > 0 {
+		top := stack[len(stack)-1]
+		stack = stack[:len(stack)-1]
+		if top > 0 { // node
+			n := s.index[top+1]
+			stack = append(stack, s.index[top+2:top+2+n]...)
+		} else { // leaf
+			top = -top - 1
+			n := s.index[top+1]
+			fn(s.index[top+2 : top+2+n])
+		}
+	}
+}