<commit_before>#!/usr/bin/env python3

# Script to print pictures using the NanoLab Microcontroller
# Microcontroller Model: Micos 1860SMC Basic
# Made 2019, <NAME>
# sunyudong [at] outlook [dot] sg
# github.com/sunjerry019/photonLauncher

from PIL import Image
# Pillow reqs https://pillow.readthedocs.io/en/5.1.x/installation.html
# We use Pillow instead of OpenCV to reduce installation overhead
# This comes at the price of speed

# import micron
import numpy as np
import argparse
import os, sys

import micron

# from matplotlib import cm # For coloring of the cutting lines

import pickle

from extraFunctions import query_yes_no as qyn


class PicConv():
	def __init__(self, filename, scale = 1, cut = 0, allowDiagonals = False, prioritizeLeft = False, flipHorizontally = False, flipVertically = False ,frames = False, simulate = False, micronInstance = None):
		self.filename = filename
		self.scale = scale

		assert cut in (0, 1), "Invalid cut value (0 or 1)"
		self.cut = cut
		self.dontcut = self.cut ^ 1

		self.allowDiagonals = allowDiagonals
		self.prioritizeLeft = prioritizeLeft
		self.flipHorizontally = flipHorizontally
		self.flipVertically = flipVertically

		self.frames = frames if not simulate else True
		self.simulate = simulate

		self.controller = micronInstance

		print("Using '{}' at scale {}".format(self.filename, self.scale))
		print("Cutting {} parts".format(["Black", "White"][self.cut]))
		if self.allowDiagonals:
			print("Allow Diagonals")

	def convert(self):
		self.image = Image.open(self.filename)

		# Sanity Checks
		assert self.image.mode == '1', "Your image has mode {}. Please use a 1-bit indexed (mode 1) image, see https://pillow.readthedocs.io/en/stable/handbook/concepts.html#bands. If using GIMP to convert picture to 1-bit index, ensure 'remove colour from palette' is unchecked".format(self.image.mode)
		# Check if size is within limits if talking directly stage
		# TODO

		self.imageArray = np.array(self.image, dtype=int)
		# We flip the image about the horizontal and vertical to match with stage position, if necessary
		if self.flipVertically:
			self.imageArray = np.flipud(self.imageArray)
		if self.flipHorizontally:
			self.imageArray = np.fliplr(self.imageArray)


		# 1 = White
		# 0 = Black

		# Main algorithm part
		# We have a function that finds the next point to cut
		# From that point, we start crawling around for neighbours based on some settings (self.directions)
		# If a right block was found, the right diagonals will be prioritized, and vice versa for the left
		# Prioritize left searches from left to right instead of right to left, helping with diagonals that points Southwest (SW)
		# Origin is top left corner

		RIGHT = (  0,  1)
		LEFT  = (  0, -1)
		UP    = ( -1,  0)
		DOWN  = (  1,  0)
		DIRSE = (  1,  1)
		DIRSW = (  1, -1)
		DIRNE = ( -1,  1)
		DIRNW = ( -1, -1)

		# Var defs
		self.shape = np.shape(self.imageArray) # (y, x)
		self.lines = []

		# These are the directions we prioritize
		if self.prioritizeLeft:
			self.directions = [LEFT, RIGHT, DOWN, DIRSW, DIRNW, UP, DIRSE, DIRNE] if self.allowDiagonals else [LEFT, RIGHT, DOWN, UP]
		else:
			self.directions = [RIGHT, LEFT, DOWN, DIRSE, DIRNE, UP, DIRSW, DIRNW] if self.allowDiagonals else [RIGHT, LEFT, DOWN, UP]

		self.output = np.zeros_like(self.imageArray)

		# Func defs
		def find_next(self, point):
			# Find the next starting point to cut
			y, x = point

			if self.prioritizeLeft:
				while y < self.shape[0]:
					x = self.shape[1] - 1
					while x >= 0:
						if self.imageArray[y, x] == self.cut:
							return (y, x)
						x -= 1
					y += 1
			else:
				while y < self.shape[0]:
					x = 0
					while x < self.shape[1]:
						if self.imageArray[y, x] == self.cut:
							return (y, x)
						x += 1
					y += 1

			return None

		def find_neighbour(self, point):
			# Find a neighbour of the current point to cut, if exists
			y, x = point
			for tup in self.directions:
				coord = (y + tup[0], x + tup[1])
				# print("At {}, Looking at {} = {}".format(point, tup, self.imageArray[coord]))
				try:
					if self.imageArray[coord] == self.cut:
						if self.allowDiagonals:
							if self.prioritizeLeft:
								if tup in (LEFT, DIRSW, DIRNW):
									self.directions = [LEFT, RIGHT, DOWN, DIRSW, DIRNW, UP, DIRSE, DIRNE]
								elif tup in (RIGHT, DIRSE, DIRNE):
									self.directions = [LEFT, RIGHT, DOWN, DIRSE, DIRNE, UP, DIRSW, DIRNW]
							else:
								if tup in (LEFT, DIRSW, DIRNW):
									self.directions = [RIGHT, LEFT, DOWN, DIRSW, DIRNW, UP, DIRSE, DIRNE]
								elif tup in (RIGHT, DIRSE, DIRNE):
									self.directions = [RIGHT, LEFT, DOWN, DIRSE, DIRNE, UP, DIRSW, DIRNW]
						return coord
				except IndexError as e:
					pass

			return None

		if self.frames:
			self.resultCount = 0
			os.system("rm results/*")
			def print_result(self, final = False):
				# normalize the output
				# np.savetxt('test.csv', self.output, delimiter=',')
				_max = np.max(self.output)
				_output = self.output / _max if _max != 0 else self.output

				_im = Image.fromarray(np.uint8((_output)*255)) # cm.gist_ncar
				if not final:
					_im.save("results/test-{}.png".format(self.resultCount))
				else:
					_im.save("test.png")
				# https://stackoverflow.com/questions/10965417/how-to-convert-numpy-array-to-pil-image-applying-matplotlib-colormap

				self.resultCount += 1
		else:
			def print_result(self, final):
				# final is there just to eat up the parameter passed in
				# normalize the output
				# np.savetxt('test.csv', self.output, delimiter=',')
				_max = np.max(self.output)
				_output = self.output / _max if _max != 0 else self.output

				# _im = Image.fromarray(np.uint8(cm.gist_ncar(_output)*255))
				_im = Image.fromarray(np.uint8((_output)*255))
				_im.save("test.png")
				# https://stackoverflow.com/questions/10965417/how-to-convert-numpy-array-to-pil-image-applying-matplotlib-colormap


		startPt = (0, 0) if not self.prioritizeLeft else (0, self.shape[1] - 1)
		lineNo  = 0
		currLine = []

		while True:
			if len(currLine):
				self.lines.append(currLine)
				currLine = []

			lineNo  += 1

			nextPt = find_next(self, startPt)
			if nextPt is None:
				break
			startPt = nextPt

			print("At point ({1:>3}:{0:>3})".format(*nextPt), end='\r')
<commit_msg>user ncar cm gist if possible<commit_after>#!/usr/bin/env python3

# Script to print pictures using the NanoLab Microcontroller
# Microcontroller Model: Micos 1860SMC Basic
# Made 2019, <NAME>
# sunyudong [at] outlook [dot] sg
# github.com/sunjerry019/photonLauncher

from PIL import Image
# Pillow reqs https://pillow.readthedocs.io/en/5.1.x/installation.html
# We use Pillow instead of OpenCV to reduce installation overhead
# This comes at the price of speed

# import micron
import numpy as np
import argparse
import os, sys

import micron

import platform

if platform.system() == "Linux":
	from matplotlib import cm # For coloring of the cutting lines

import pickle

from extraFunctions import query_yes_no as qyn


class PicConv():
	def __init__(self, filename, scale = 1, cut = 0, allowDiagonals = False, prioritizeLeft = False, flipHorizontally = False, flipVertically = False ,frames = False, simulate = False, micronInstance = None):
		self.filename = filename
		self.scale = scale

		assert cut in (0, 1), "Invalid cut value (0 or 1)"
		self.cut = cut
		self.dontcut = self.cut ^ 1

		self.allowDiagonals = allowDiagonals
		self.prioritizeLeft = prioritizeLeft
		self.flipHorizontally = flipHorizontally
		self.flipVertically = flipVertically

		self.frames = frames if not simulate else True
		self.simulate = simulate

		self.controller = micronInstance

		print("Using '{}' at scale {}".format(self.filename, self.scale))
		print("Cutting {} parts".format(["Black", "White"][self.cut]))
		if self.allowDiagonals:
			print("Allow Diagonals")

	def convert(self):
		self.image = Image.open(self.filename)

		# Sanity Checks
		assert self.image.mode == '1', "Your image has mode {}. Please use a 1-bit indexed (mode 1) image, see https://pillow.readthedocs.io/en/stable/handbook/concepts.html#bands. If using GIMP to convert picture to 1-bit index, ensure 'remove colour from palette' is unchecked".format(self.image.mode)
		# Check if size is within limits if talking directly stage
		# TODO

		self.imageArray = np.array(self.image, dtype=int)
		# We flip the image about the horizontal and vertical to match with stage position, if necessary
		if self.flipVertically:
			self.imageArray = np.flipud(self.imageArray)
		if self.flipHorizontally:
			self.imageArray = np.fliplr(self.imageArray)


		# 1 = White
		# 0 = Black

		# Main algorithm part
		# We have a function that finds the next point to cut
		# From that point, we start crawling around for neighbours based on some settings (self.directions)
		# If a right block was found, the right diagonals will be prioritized, and vice versa for the left
		# Prioritize left searches from left to right instead of right to left, helping with diagonals that points Southwest (SW)
		# Origin is top left corner

		RIGHT = (  0,  1)
		LEFT  = (  0, -1)
		UP    = ( -1,  0)
		DOWN  = (  1,  0)
		DIRSE = (  1,  1)
		DIRSW = (  1, -1)
		DIRNE = ( -1,  1)
		DIRNW = ( -1, -1)

		# Var defs
		self.shape = np.shape(self.imageArray) # (y, x)
		self.lines = []

		# These are the directions we prioritize
		if self.prioritizeLeft:
			self.directions = [LEFT, RIGHT, DOWN, DIRSW, DIRNW, UP, DIRSE, DIRNE] if self.allowDiagonals else [LEFT, RIGHT, DOWN, UP]
		else:
			self.directions = [RIGHT, LEFT, DOWN, DIRSE, DIRNE, UP, DIRSW, DIRNW] if self.allowDiagonals else [RIGHT, LEFT, DOWN, UP]

		self.output = np.zeros_like(self.imageArray)

		# Func defs
		def find_next(self, point):
			# Find the next starting point to cut
			y, x = point

			if self.prioritizeLeft:
				while y < self.shape[0]:
					x = self.shape[1] - 1
					while x >= 0:
						if self.imageArray[y, x] == self.cut:
							return (y, x)
						x -= 1
					y += 1
			else:
				while y < self.shape[0]:
					x = 0
					while x < self.shape[1]:
						if self.imageArray[y, x] == self.cut:
							return (y, x)
						x += 1
					y += 1

			return None

		def find_neighbour(self, point):
			# Find a neighbour of the current point to cut, if exists
			y, x = point
			for tup in self.directions:
				coord = (y + tup[0], x + tup[1])
				# print("At {}, Looking at {} = {}".format(point, tup, self.imageArray[coord]))
				try:
					if self.imageArray[coord] == self.cut:
						if self.allowDiagonals:
							if self.prioritizeLeft:
								if tup in (LEFT, DIRSW, DIRNW):
									self.directions = [LEFT, RIGHT, DOWN, DIRSW, DIRNW, UP, DIRSE, DIRNE]
								elif tup in (RIGHT, DIRSE, DIRNE):
									self.directions = [LEFT, RIGHT, DOWN, DIRSE, DIRNE, UP, DIRSW, DIRNW]
							else:
								if tup in (LEFT, DIRSW, DIRNW):
									self.directions = [RIGHT, LEFT, DOWN, DIRSW, DIRNW, UP, DIRSE, DIRNE]
								elif tup in (RIGHT, DIRSE, DIRNE):
									self.directions = [RIGHT, LEFT, DOWN, DIRSE, DIRNE, UP, DIRSW, DIRNW]
						return coord
				except IndexError as e:
					pass

			return None

		if self.frames:
			self.resultCount = 0
			os.system("rm results/*")
			def print_result(self, final = False):
				# normalize the output
				# np.savetxt('test.csv', self.output, delimiter=',')
				_max = np.max(self.output)
				_output = self.output / _max if _max != 0 else self.output

				_im = Image.fromarray(np.uint8((_output)*255)) # cm.gist_ncar
				if not final:
					_im.save("results/test-{}.png".format(self.resultCount))
				else:
					_im.save("test.png")
				# https://stackoverflow.com/questions/10965417/how-to-convert-numpy-array-to-pil-image-applying-matplotlib-colormap

				self.resultCount += 1
		else:
			def print_result(self, final):
				# final is there just to eat up the parameter passed in
				# normalize the output
				# np.savetxt('test.csv', self.output, delimiter=',')
				_max = np.max(self.output)
				_output = self.output / _max if _max != 0 else self.output

				try:
					_im = Image.fromarray(np.uint8(cm.gist_ncar(_output)*255))
				except NameError as e:
					_im = Image.fromarray(np.uint8((_output)*255))
				_im.save("test.png")
				# https://stackoverflow.com/questions/10965417/how-to-convert-numpy-array-to-pil-image-applying-matplotlib-colormap


		startPt = (0, 0) if not self.prioritizeLeft else (0, self.shape[1] - 1)
		lineNo  = 0
		currLine = []

		while True:
			if len(currLine):
				self.lines.append(currLine)
				currLine = []

			lineNo  += 1

			nextPt = find_next(self, startPt)
			if nextPt is None:
				break
			startPt = nextPt

			print("At point ({1:>3}:{0:>3})".format(*nextPt), end='\r')

{'fraction_non_alphanumeric': 0.11887283921382903, 'fraction_numerical': 0.015628699976320153, 'mean_word_length': 3.1405228758169934, 'pattern_counts': {'":': 1, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6391320', 'n_tokens_mistral': 5328, 'n_tokens_neox': 4352, 'n_words': 1329}