view cmd/octree2contour/main.go @ 686:a2f107f1e4e7 octree

octree: run each slice in contour tool concurrently.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 20 Sep 2018 00:13:47 +0200
parents a8d32a11b113
children be90ab542aa7
line wrap: on
line source

package main

import (
	"flag"
	"log"
	"runtime"
	"sort"
	"sync"
	"time"
)

var (
	one  = flag.Bool("o", false, "create only a single contour")
	step = flag.Float64("s", 0.5, "step with")
	max  = flag.Float64("m", 10, "max height from lowest point")
)

type result struct {
	h         float64
	triangles int
}

func processLevels(
	tree *octree,
	jobs <-chan float64,
	results chan<- result,
	wg *sync.WaitGroup,
) {
	defer wg.Done()
	for h := range jobs {
		var triangles int
		tree.horizontal(h, func([]int32) {
			triangles++
		})
		results <- result{h, triangles}
	}
}

func process(tree *octree) {
	var triangles int
	start := time.Now()
	if *one {
		tree.horizontal(*step, func([]int32) {
			triangles++
		})
	} else {

		results := make(chan result)
		done := make(chan struct{})

		var all []result

		go func() {
			for {
				select {
				case r := <-results:
					all = append(all, r)
				case <-done:
					return
				}
			}
		}()

		var wg sync.WaitGroup
		jobs := make(chan float64)
		for i, n := 0, runtime.NumCPU(); i < n; i++ {
			wg.Add(1)
			go processLevels(tree, jobs, results, &wg)
		}
		for h := tree.min.z; h <= tree.max.z; h += *step {
			jobs <- h
		}
		close(jobs)
		wg.Wait()
		done <- struct{}{}

		sort.Slice(all, func(i, j int) bool {
			return all[i].h < all[j].h
		})

		var sum int
		for i := range all {
			a := &all[i]
			sum += a.triangles
			log.Printf("level %f: %d\n", a.h, a.triangles)
		}
		log.Printf("num triangles: %d\n", sum)
	}
	log.Printf("processing took: %s\n", time.Since(start))
}

func main() {
	flag.Parse()

	for _, fname := range flag.Args() {
		log.Printf("processing %s\n", fname)
		start := time.Now()
		tree, err := loadOctree(fname)
		if err != nil {
			log.Printf("error: %v\n", err)
			continue
		}
		log.Printf("loading took: %v\n", time.Since(start))
		process(tree)
	}
}