예제 #1
0
파일: optimize.go 프로젝트: krasin/voxel
func main() {
	timing.StartTiming("total")
	timing.StartTiming("Read STL from Stdin")
	triangles, err := stl.Read(os.Stdin)
	if err != nil {
		log.Fatalf("stl.Read: %v", err)
	}
	timing.StopTiming("Read STL from Stdin")

	timing.StartTiming("STLToMesh")
	mesh := raster.STLToMesh(VoxelSide*MeshMultiplier, triangles)
	timing.StopTiming("STLToMesh")

	timing.StartTiming("MeshVolume")
	volume := triangle.MeshVolume(mesh.Triangle, 1)
	if volume < 0 {
		volume = -volume
	}
	fmt.Fprintf(os.Stderr, "Mesh volume (in mesh units): %d\n", volume)
	timing.StopTiming("MeshVolume")

	timing.StartTiming("Rasterize")
	vol := raster.Rasterize(mesh, VoxelSide)
	timing.StopTiming("Rasterize")

	timing.StartTiming("Optimize")
	Optimize(vol, 22)
	timing.StopTiming("Optimize")

	/*	timing.StartTiming("Write nptl")
		if err = nptl.Write(os.Stdout, vol, mesh.Grid); err != nil {
			log.Fatalf("nptl.Write: %v", err)
		}
		v := vol.Volume()
		fmt.Fprintf(os.Stderr, "Volume is filled by %v%%\n", float64(v)*float64(100)/(float64(vol.N())*float64(vol.N())*float64(vol.N())))
		timing.StopTiming("Write nptl")
	*/

	side := mesh.Grid.Side()
	vsize := surface.Vector{side, side, side}
	t := surface.MarchingCubes(NewVolumeField2(vol), 128, 0.8, vsize)
	var f *os.File
	if f, err = os.OpenFile("output.stl", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
		log.Fatal(err)
	}
	if err = stl.WriteBinary(f, t); err != nil {
		log.Fatalf("stl.Write: %v", err)
	}
	f.Close()

	timing.StopTiming("total")
	timing.PrintTimings(os.Stderr)
}
예제 #2
0
파일: rasterize.go 프로젝트: krasin/voxel
func Rasterize(m Mesh, n int) volume.Space16 {
	scale := m.N / n
	vol := volume.NewSparseVolume(n)

	timing.StartTiming("Rasterize triangles")
	for index, t := range m.Triangle {
		triangle.AllTriangleDots(t[0], t[1], t[2], int64(scale), vol, uint16(1+(index%10)))
	}
	fmt.Fprintf(os.Stderr, "Triangle rasterization complete\n")
	timing.StopTiming("Rasterize triangles")

	timing.StartTiming("Rasterize cubes")
	ds := set.NewDisjoinSet()
	// Reserve color for outer space
	ds.Make()

	shift := 11

	// Let's color cubes.
	for k, cube := range vol.Cubes {
		// Skip cubes with leaf voxels
		if cube != nil {
			continue
		}
		p := volume.K2cube(k)

		// If this is a cube at the edge of the space, it's a part of outer space.
		if p[0] == 0 || p[1] == 0 || p[2] == 0 ||
			int(p[0]) == (1<<uint(vol.LK))-1 || int(p[1]) == (1<<uint(vol.LK))-1 || int(p[2]) == (1<<uint(vol.LK))-1 {
			vol.Colors[k] = uint16(shift + ds.Find(0))
			continue
		}

		// Look if any neighbour has already color assigned
		for i := 0; i < 3; i++ {
			for j := -1; j <= 1; j += 2 {
				p2 := p
				p2[i] = p2[i] + j
				k2 := volume.Cube2k(p2)
				if k2 >= len(vol.Colors) {
					panic(fmt.Sprintf("k2: %d, len(vol.Colors): %d, len(vol.Cubes): %d, p: %v, p2: %v, k: %d", k2, len(vol.Colors), len(vol.Cubes), p, p2, k))
				}
				if vol.Colors[k2] == 0 {
					continue
				}
				if vol.Colors[k] == 0 {
					vol.Colors[k] = vol.Colors[k2]
				} else {
					ds.Join(int(vol.Colors[k])-shift, int(vol.Colors[k2])-shift)
				}
			}
		}

		// If there's no colored neighbour, introduce a new color.
		if vol.Colors[k] == 0 {
			vol.Colors[k] = uint16(shift + ds.Make())
		}
	}
	timing.StopTiming("Rasterize cubes")
	timing.StartTiming("Rasterize leaf voxels")

	// Now, we need to go through cubes which have leaf voxels
	for k, cube := range vol.Cubes {
		if cube == nil {
			continue
		}
		for h, val := range cube {
			if val != 0 {
				continue
			}
			p := volume.Kh2point(k, h)
			color := val
			// Look for neighbours of this leaf voxel
			for i := 0; i < 3; i++ {
				for j := -1; j <= 1; j += 2 {
					p2 := p
					p2[i] = p2[i] + j
					color2 := vol.Get16(g3.Node{int(p2[0]), int(p2[1]), int(p2[2])})
					if int(color2) < shift {
						continue
					}
					if color == 0 {
						vol.Set16(g3.Node{int(p[0]), int(p[1]), int(p[2])}, color2)
						color = color2
					} else {
						ds.Join(int(color)-shift, int(color2)-shift)
					}
				}
			}
			if color == 0 {
				vol.Set16(g3.Node{int(p[0]), int(p[1]), int(p[2])}, uint16(shift+ds.Make()))
			}
		}
	}
	timing.StopTiming("Rasterize leaf voxels")

	timing.StartTiming("Rasterize.CanonicalizeColors")
	// Canonicalize colors
	canonicalZero := uint16(shift + ds.Find(0))
	for k, cube := range vol.Cubes {
		if cube == nil {
			vol.Colors[k] = uint16(shift + ds.Find(int(vol.Colors[k])-shift))
			if vol.Colors[k] == canonicalZero {
				vol.Colors[k] = 0
			}
			continue
		}
		for h := 0; h < len(cube); h++ {
			if int(cube[h]) < shift {
				continue
			}
			cube[h] = uint16(shift + ds.Find(int(cube[h])-shift))
			if cube[h] == canonicalZero {
				cube[h] = 0
			}
		}
	}
	timing.StopTiming("Rasterize.CanonicalizeColors")

	timing.StartTiming("Rasterize.DrawSlices")
	bmp := image.NewRGBA(image.Rect(0, 0, n, n))
	for z := 1; z < n; z++ {
		if z%10 == 0 {
			for x := 0; x < n; x++ {
				for y := 0; y < n; y++ {
					v := vol.Get16(g3.Node{x, y, z})
					if int(v) < len(colors) {
						bmp.Set(x, y, colors[v])
					} else {
						bmp.Set(x, y, PinkX(int(v)))
					}
				}
			}

			f, _ := os.OpenFile(fmt.Sprintf("zban-%03d.png", z), os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0666)
			png.Encode(f, bmp)
			f.Close()
		}
	}
	timing.StopTiming("Rasterize.DrawSlices")
	fmt.Fprintf(os.Stderr, "Rasterize complete\n")
	return vol
}