< up >
2022-01-14 12:46:28 +0100 CET

AoC 2021 day 9 - 3D print of cave height map

After solving the puzzle of day 9 about a cave with basins and heights from 0 to 9, we[1] thought about 3D printing the input as height map.

Go program

I generated an STL model using the puzzle input as list of lines:

func renderSTL(input []string) {
  filename := "day09.stl"

  // list of all generated boxes
  boxes := make([]sdf.SDF3, 0)

  // base plate on which the height 0 begins 
  plate2d := sdf.Box2D(sdf.V2{float64(len(input)), float64(len(input[0]))}, 1)
  plate3d := sdf.Extrude3D(plate2d, 2.0)
  // Move plate completely to the positive space. Initially the center of the
  // plate is positioned at the origin.
  plateM := sdf.Translate3d(sdf.V3{
    float64(len(input)) / 2,
    float64(len(input[0])) / 2,
    0,
  })

  boxes = append(boxes, sdf.Transform3D(plate3d, plateM))
  for y, row := range input {
    for x, cell := range row {
      if cell == '0' {
        continue
      }
      num, err := strconv.Atoi(string(cell))
      if err != nil {
        fmt.Printf("error converting %d\n", cell)
        return
      }
      box2d := sdf.Box2D(sdf.V2{1, 1}, 0)
      // add one so level 0 has one unit
      height := float64(num + 1)
      box3d := sdf.Extrude3D(box2d, height)
      m := sdf.Translate3d(sdf.V3{float64(x), float64(y), height / 2})
      boxes = append(boxes, sdf.Transform3D(box3d, m))

    }
  }

  fmt.Printf("generated %d boxes\n", len(boxes))
  start := time.Now()
  render.RenderSTL(sdf.Union3D(boxes...), 400, filename)
  fmt.Printf("needed %s\n", time.Since(start))
}

Impressions

[1] credits to Markus