def paintcycle(dict):
					for colour in dict:
						paintHat(dict[colour], REDVMTFile)
						SendKeys("""{F5}""")
						mouse.sleep(0.1)
						imgWhiteBG = ImageGrab.grab()
						imgWhiteBG = imgWhiteBG.crop(imgCropBoundaries)
						whiteBackgroundImages[colour] = imgWhiteBG
					# Change BG colour to black
					SendKeys("""^b""")
					# Take blackBG screenshots and crop
					for colour in dict:
						paintHat(dict[colour], REDVMTFile)
						SendKeys("""{F5}""")
						mouse.sleep(0.1)
						imgBlackBG = ImageGrab.grab()
						imgBlackBG = imgBlackBG.crop(imgCropBoundaries)
						blackBackgroundImages[colour] = imgBlackBG
					SendKeys("""^b""")
				def paintcycle(dict, whiteBackgroundImages, blackBackgroundImages):
					# Take whiteBG screenshots and crop
					for colour in dict:
						paintHat(dict[colour], REDVMTFile)
						SendKeys(r'{F5}')
						mouse.sleep(0.1)
						imgWhiteBG = screenshot()
						imgWhiteBG = imgWhiteBG.crop(imgCropBoundaries)
						whiteBackgroundImages[colour] = imgWhiteBG
					# Change BG colour to black
					SendKeys(r'^b')
					# Take blackBG screenshots and crop
					for colour in dict:
						paintHat(dict[colour], REDVMTFile)
						SendKeys(r'{F5}')
						mouse.sleep(0.1)
						imgBlackBG = screenshot()
						imgBlackBG = imgBlackBG.crop(imgCropBoundaries)
						blackBackgroundImages[colour] = imgBlackBG
					SendKeys(r'^b')
					SendKeys(r'{F5}')
					return whiteBackgroundImages, blackBackgroundImages
def automateDis(model, numberOfImages=24, n=0, rotationOffset=None, initialRotation=None, initialTranslation=None, verticalOffset=None, disableXRotation=False, REDVMTFile=None, BLUVMTFile=None):
	""" Method to automize process of taking images for 3D model views. 
	
		Parameters:
                model -> An instance of a HLMVModelRegistryKey object for the model. Required.
				numberOfImages -> Number of images to take for one full rotation. Optional, default is 24.
				n -> Which nth step of rotation to start at. Optional, default is 0.
				rotationOffset -> The distance from the default centre of rotation to the new one (in HLMV units). Optional, default is none.
				initialRotation -> The initial model rotation as a tuple. Optional, default is (0 0 0).
				initialTranslation -> The initial model translation as a tuple. Optional, default is (0 0 0).
				verticalOffset -> The vertical offset for models that are centered in both other planes but not vertically. Optional, default is none.
				disableXRotation -> Boolean that disables tilting. Default is False.
	"""
	
	folder = raw_input('Folder name for created images: ')
	outputFolder = outputImagesDir + os.sep + folder
	try:
		os.mkdir(outputFolder)
	except:
		answer = raw_input('Folder already exists, overwrite files? y\\n? ')
		if answer == 'yes' or answer == 'y':
			pass
		elif answer == 'no' or answer == 'n':
			sys.exit(1)
	
	if initialTranslation is None:
		initialTranslation = [model.returnTranslation()['x'], model.returnTranslation()['y'], model.returnTranslation()['z']]
	if initialRotation is None:
		initialRotation = [model.returnRotation()['x'], model.returnRotation()['y'], model.returnRotation()['z']]
	
	# Time for user to cancel script start
	mouse.sleep(3)
	
	try:
		subprocess.Popen(['taskkill', '/f', '/t' ,'/im', 'hlmv.exe'], stdout=PIPE, stderr=PIPE)
		mouse.sleep(2)
	except:
		pass
	print 'initialTranslation =', initialTranslation
	print 'initialRotation =', initialRotation
	model.setTranslation(x = initialTranslation[0], y = initialTranslation[1], z = initialTranslation[2])
	model.setNormalMapping(True)
	SDKLauncherCoords = None
	
	whiteBackgroundImages = {}
	blackBackgroundImages = {}
	
	for yrotation in range((-180 + (360/24 * n)), 180, 360/numberOfImages):
		print 'n =', str(n)
		for xrotation in range(-15, 30, 15):
			if (disableXRotation and xrotation == 0) or not disableXRotation:
				# Set rotation
				mouse.sleep(0.5)
				model.setRotation(x = xrotation + float(initialRotation[0]), y = yrotation + float(initialRotation[1]), z = initialRotation[2])
				print 'xRot = %s, yRot = %s' % (xrotation, yrotation)
				if rotationOffset is not None:
					# Set translation to account for off centre rotation
					result = rotateAboutNewCentre(initialTranslation[0], initialTranslation[1], initialTranslation[2], rotationOffset, yrotation, xrotation)
					print 'translation =', result
					model.setTranslation(x = result[0], y = result[1], z = result[2])
					# Set translation to account for off centre horizontal rotation
				elif verticalOffset is not None:
					result = offsetVertically(initialTranslation[0], initialTranslation[1], initialTranslation[2], verticalOffset, yrotation, xrotation)
					print 'translation =', result
					model.setTranslation(x = result[0], y = result[1], z = result[2])
				# Set white colour
				model.setBGColour(255, 255, 255, 255)
				# Open HLMV
				mouse.sleep(1)
				if SDKLauncherCoords is None:
					SDKLauncherCoords = mouse.find({targetImagesDir + os.sep + 'openhlmv.png': (0, 0)}, startingPoint=SDKLauncherStartingPoint)
					if SDKLauncherCoords is None:
						SDKLauncherCoords = mouse.find({targetImagesDir + os.sep + 'openhlmvunhighlighted.png': (0, 0)}, startingPoint=SDKLauncherStartingPoint)
					if SDKLauncherCoords is None:
						SDKLauncherCoords = mouse.find({targetImagesDir + os.sep + 'openhlmvinactive.png': (0, 0)}, startingPoint=SDKLauncherStartingPoint)
					if SDKLauncherCoords is None:
						print 'Couldn\'t find source SDK launcher to click on'
						break
				mouse.doubleclick(SDKLauncherCoords)
				# Maximise HLMV
				mouse.sleep(2)
				SendKeys("""*{UP}""")
				# Open recent model
				mouse.click(x=fileButtonCoordindates[0],y=fileButtonCoordindates[1])
				SendKeys("""{DOWN 8}{RIGHT}{ENTER}""")
				# Take whiteBG screenshots and crop
				mouse.sleep(2)
				def paintcycle(dict):
					for colour in dict:
						paintHat(dict[colour], REDVMTFile)
						SendKeys("""{F5}""")
						mouse.sleep(0.1)
						imgWhiteBG = ImageGrab.grab()
						imgWhiteBG = imgWhiteBG.crop(imgCropBoundaries)
						whiteBackgroundImages[colour] = imgWhiteBG
					# Change BG colour to black
					SendKeys("""^b""")
					# Take blackBG screenshots and crop
					for colour in dict:
						paintHat(dict[colour], REDVMTFile)
						SendKeys("""{F5}""")
						mouse.sleep(0.1)
						imgBlackBG = ImageGrab.grab()
						imgBlackBG = imgBlackBG.crop(imgCropBoundaries)
						blackBackgroundImages[colour] = imgBlackBG
					SendKeys("""^b""")
				paintcycle(paintDict)
				# Change RED hat to BLU
				redVMTContents = open(REDVMTFile, 'rb').read()
				bluVMTContents = open(BLUVMTFile, 'rb').read()
				f = open(REDVMTFile, 'wb')
				f.write(bluVMTContents)
				f.close()
				paintcycle(BLUPaintDict)
				g = open(REDVMTFile, 'wb')
				g.write(redVMTContents)
				g.close()
				# Remove background from images
				"""for colour in whiteBackgroundImages:
					print 'processing ' + colour
					img = toAlphaBlackWhite(blackBackgroundImages[colour], whiteBackgroundImages[colour])
					# Save screenshot
					if xrotation == -15:
						imgname = str(n) + 'up' + colour + '.png'
					elif xrotation == 15:
						imgname = str(n) + 'down' + colour + '.png'
					else:
						imgname = str(n) + '' + colour + '.png'
					img.save(outputFolder + os.sep + imgname, "PNG")"""
				BlendingThread(xrotation, n, blackBackgroundImages, whiteBackgroundImages, outputFolder)
				# Close HLMV
				subprocess.Popen(['taskkill', '/f', '/t' ,'/im', 'hlmv.exe'], stdout=PIPE, stderr=PIPE)
		n += 1
	BlendingThread.waitForAll()
	# Stitch images together
	print 'Stitching images together...'
	stitch(outputFolder, finalImageName)
	# All done yay
	print '\nAll done'
def automateDis(model,
				numberOfImages=24,
				n=0,
				rotationOffset=None,
				initialRotation=None,
				initialTranslation=None,
				verticalOffset=None,
				disableXRotation=False,
				paint=False,
				teamColours=False,
				itemName='',
				REDVMTFile=None,
				BLUVMTFile=None,
				wikiUsername=None,
				wikiPassword=None):
	""" Method to automize process of taking images for 3D model views. 
	
		Parameters:
                model -> An instance of a HLMVModelRegistryKey object for the model. Required.
				numberOfImages -> Number of images to take for one full rotation. Optional, default is 24.
				n -> Which nth step of rotation to start at. Optional, default is 0.
				rotationOffset -> The distance from the default centre of rotation to the new one (in HLMV units). Optional, default is none.
				initialRotation -> The initial model rotation as a tuple. Optional, default is (0 0 0).
				initialTranslation -> The initial model translation as a tuple. Optional, default is (0 0 0).
				verticalOffset -> The vertical offset for models that are centered in both other planes but not vertically. Optional, default is none.
				disableXRotation -> Boolean that disables tilting. Default is False.
				paint -> Boolean to indicate whether model is paintable. Optional, default is False.
				teamColours -> Boolean to indicate whether model is team coloured. Optional, default is False.
				itemName -> The name of the item. Optional, default is blank.
				REDVMTFile -> The RED vmt file location. Optional, default is none.
				BLUVMTFile -> The BLU vmt file location. Optional, default is none.
				wikiUsername -> wiki.tf2.com username. Optional, default is none.
				wikiPassword -> wiki.tf2.com password. Optional, default is none.
	"""
	folder = raw_input('Folder name for created images: ')
	outputFolder = outputImagesDir + os.sep + folder
	try:
		os.makedirs(outputFolder)
	except:
		answer = raw_input('Folder already exists, overwrite files? y\\n? ')
		if answer == 'yes' or answer == 'y':
			pass
		elif answer == 'no' or answer == 'n':
			sys.exit(1)
	
	if initialTranslation is None:
		initialTranslation = [model.returnTranslation()['x'], model.returnTranslation()['y'], model.returnTranslation()['z']]
	if initialRotation is None:
		initialRotation = [model.returnRotation()['x'], model.returnRotation()['y'], model.returnRotation()['z']]
	
	# Time for user to cancel script start
	mouse.sleep(3)
	
	try:
		subprocess.Popen(['taskkill', '/f', '/t' ,'/im', 'hlmv.exe'], stdout=PIPE, stderr=PIPE)
		mouse.sleep(2)
	except:
		pass
	print 'initialTranslation =', initialTranslation
	print 'initialRotation =', initialRotation
	
	model.setTranslation(x = initialTranslation[0], y = initialTranslation[1], z = initialTranslation[2])
	model.setNormalMapping(True)
	model.setBGColour(255, 255, 255, 255)
	SDKLauncherCoords = None
	for yrotation in range((-180 + (360/numberOfImages * n)), 180, 360/numberOfImages):
		print 'n =', str(n)
		for xrotation in range(-15, 30, 15):
			if (disableXRotation and xrotation == 0) or not disableXRotation:
				# Set rotation
				mouse.sleep(0.5)
				model.setRotation(x = xrotation + float(initialRotation[0]), y = yrotation + float(initialRotation[1]), z = initialRotation[2])
				print 'xRot = %s, yRot = %s' % (xrotation, yrotation)
				if rotationOffset is not None:
					# Set translation to account for off centre rotation
					result = rotateAboutNewCentre(initialTranslation[0], initialTranslation[1], initialTranslation[2], rotationOffset, yrotation, xrotation)
					print 'translation =', result
					model.setTranslation(x = result[0], y = result[1], z = result[2])
					# Set translation to account for off centre horizontal rotation
				elif verticalOffset is not None:
					result = offsetVertically(initialTranslation[0], initialTranslation[1], initialTranslation[2], verticalOffset, yrotation, xrotation)
					print 'translation =', result
					model.setTranslation(x = result[0], y = result[1], z = result[2])
				# Open HLMV
				if SDKLauncherCoords is None:
					SDKLauncherCoords = mouse.find({targetImagesDir + os.sep + 'openhlmv.png': (0, 0)}, startingPoint=SDKLauncherStartingPoint)
					if SDKLauncherCoords is None:
						SDKLauncherCoords = mouse.find({targetImagesDir + os.sep + 'openhlmvunhighlighted.png': (0, 0)}, startingPoint=SDKLauncherStartingPoint)
					if SDKLauncherCoords is None:
						SDKLauncherCoords = mouse.find({targetImagesDir + os.sep + 'openhlmvinactive.png': (0, 0)}, startingPoint=SDKLauncherStartingPoint)
					if SDKLauncherCoords is None:
						print 'Couldn\'t find source SDK launcher to click on'
						break
				mouse.doubleclick(SDKLauncherCoords)
				mouse.sleep(2)
				# Maximise HLMV
				SendKeys(r'*{UP}')
				# Open recent model
				mouse.click(x=fileButtonCoordindates[0],y=fileButtonCoordindates[1])
				SendKeys(r'{DOWN 8}{RIGHT}{ENTER}')
				mouse.sleep(1)
				# Item painting method
				def paintcycle(dict, whiteBackgroundImages, blackBackgroundImages):
					# Take whiteBG screenshots and crop
					for colour in dict:
						paintHat(dict[colour], REDVMTFile)
						SendKeys(r'{F5}')
						mouse.sleep(0.1)
						imgWhiteBG = screenshot()
						imgWhiteBG = imgWhiteBG.crop(imgCropBoundaries)
						whiteBackgroundImages[colour] = imgWhiteBG
					# Change BG colour to black
					SendKeys(r'^b')
					# Take blackBG screenshots and crop
					for colour in dict:
						paintHat(dict[colour], REDVMTFile)
						SendKeys(r'{F5}')
						mouse.sleep(0.1)
						imgBlackBG = screenshot()
						imgBlackBG = imgBlackBG.crop(imgCropBoundaries)
						blackBackgroundImages[colour] = imgBlackBG
					SendKeys(r'^b')
					SendKeys(r'{F5}')
					return whiteBackgroundImages, blackBackgroundImages
				if paint:
					whiteBackgroundImages = {}
					blackBackgroundImages = {}
					whiteBackgroundImages, blackBackgroundImages = paintcycle(paintDict, whiteBackgroundImages, blackBackgroundImages)
					if teamColours:
						# Change RED hat to BLU
						redVMTContents = open(REDVMTFile, 'rb').read()
						bluVMTContents = open(BLUVMTFile, 'rb').read()
						f = open(REDVMTFile, 'wb')
						f.write(bluVMTContents)
						f.close()
						whiteBackgroundImages, blackBackgroundImages = paintcycle(BLUPaintDict, whiteBackgroundImages, blackBackgroundImages)
						g = open(REDVMTFile, 'wb')
						g.write(redVMTContents)
						g.close()
					else:
						whiteBackgroundImages, blackBackgroundImages = paintcycle(BLUPaintDict, whiteBackgroundImages, blackBackgroundImages)
				else:
					if teamColours:
						# Take whiteBG screenshot and crop
						imgWhiteBGRED = screenshot()
						imgWhiteBGRED = imgWhiteBGRED.crop(imgCropBoundaries)
						# Change BG colour to black
						SendKeys(r'^b')
						# Take blackBG screenshot and crop
						imgBlackBGRED = screenshot()
						imgBlackBGRED = imgBlackBGRED.crop(imgCropBoundaries)
						# Change BG colour to white
						SendKeys(r'^b')
						# Change weapon colour to BLU
						redVMTContents = open(REDVMTFile, 'rb').read()
						bluVMTContents = open(BLUVMTFile, 'rb').read()
						f = open(REDVMTFile, 'wb')
						f.write(bluVMTContents)
						f.close()
						SendKeys(r'{F5}')
						mouse.sleep(0.1)
						# Take whiteBG screenshot and crop
						imgWhiteBGBLU = screenshot()
						imgWhiteBGBLU = imgWhiteBGBLU.crop(imgCropBoundaries)
						# Change BG colour to black
						SendKeys(r'^b')
						# Take blackBG screenshot and crop
						imgBlackBGBLU = screenshot()
						imgBlackBGBLU = imgBlackBGBLU.crop(imgCropBoundaries)
						# Return VMT back to RED
						g = open(REDVMTFile, 'wb')
						g.write(redVMTContents)
						g.close()
					else:
						# Take whiteBG screenshot and crop
						imgWhiteBG = screenshot()
						imgWhiteBG = imgWhiteBG.crop(imgCropBoundaries)
						# Change BG colour to black
						SendKeys(r'^b')
						# Take blackBG screenshot and crop
						imgBlackBG = screenshot()
						imgBlackBG = imgBlackBG.crop(imgCropBoundaries)
				# Remove background from images
				if paint:
					blendingMachine(xrotation, n, blackBackgroundImages, whiteBackgroundImages, outputFolder, True, True)
				else:
					if teamColours:
						blendingMachine(xrotation, n, {'RED':imgBlackBGRED,'BLU':imgBlackBGBLU}, {'RED':imgWhiteBGRED,'BLU':imgWhiteBGBLU}, outputFolder, False, True)
					else:
						blendingMachine(xrotation, n, imgBlackBG, imgWhiteBG, outputFolder, False, False)
				# Close HLMV
				subprocess.Popen(['taskkill', '/f', '/t' ,'/im', 'hlmv.exe'], stdout=PIPE, stderr=PIPE)
				# Check for kill switch
				killKeyState = GetKeyState(VK_CAPITAL)
				if killKeyState in [1, -127]:
					print '\nSuccessfully terminated'
					sys.exit(0)
		n += 1
	blendingMachine() # Wait for threads to finish, if any
	# Stitch images together
	print 'Stitching images together...'
	stitchPool = threadpool(numThreads=2, defaultTarget=stitch)
	if paint:
		for colour in paintHexDict:
			if colour == 'Stock':
				if teamColours:
					finalImageName = itemName + ' RED ' + '3D.jpg'
				else:
					finalImageName = itemName + ' 3D.jpg'
			elif colour == 'Stock (BLU)':
				if teamColours:
					finalImageName = itemName + ' BLU ' + '3D.jpg'
				else:
					pass
			else:
				finalImageName = itemName + ' ' + paintHexDict[colour] + ' 3D.jpg'
			##### Need to thread this #####
			if colour == 'Stock (BLU)' and not teamColours:
				pass
			else:
				stitchPool(outputFolder, paintHexDict[colour], finalImageName, numberOfImages)
	else:
		if teamColours:
			finalREDImageName = itemName + ' RED 3D.jpg'
			finalBLUImageName = itemName + ' BLU 3D.jpg'
			stitchPool(outputFolder, ' RED', finalREDImageName, numberOfImages)
			stitchPool(outputFolder, ' BLU', finalBLUImageName, numberOfImages)
		else:
			finalImageName = itemName + ' 3D.jpg'
			stitchPool(outputFolder, None, finalImageName, numberOfImages)
	stitchPool.shutdown()
	# Upload images to wiki
	if paint:
		for colour in paintHexDict:
			if colour == 'Stock':
				if teamColours:
					fileName = itemName + ' RED ' + '3D.jpg'
				else:
					fileName = itemName + ' 3D.jpg'
			elif colour == 'Stock (BLU)':
				if teamColours:
					fileName = itemName + ' BLU ' + '3D.jpg'
				else:
					pass
			else:
				fileName = itemName + ' ' + paintHexDict[colour] + ' 3D.jpg'
			url = fileURL(fileName)
			description = open(outputFolder + os.sep + fileName + ' offsetmap.txt', 'rb').read()
			description = description.replace('url = <nowiki></nowiki>','url = <nowiki>' + url + '</nowiki>')
			if colour == 'Stock (BLU)' and not TeamColours:
				pass
			else:
				uploadFile(outputFolder + os.sep + fileName, fileName, description, wikiUsername, wikiPassword, category='', overwrite=False)
	else:
		if teamColours:
			finalREDImageName = itemName + ' RED 3D.jpg'
			finalBLUImageName = itemName + ' BLU 3D.jpg'
			url = fileURL(finalREDImageName)
			url2 = fileURL(finalBLUImageName)
			description = open(outputFolder + os.sep + finalREDImageName + ' offsetmap.txt', 'rb').read()
			description = description.replace('url = <nowiki></nowiki>','url = <nowiki>' + url + '</nowiki>')
			description2 = open(outputFolder + os.sep + finalBLUImageName + ' offsetmap.txt', 'rb').read()
			description2 = description2.replace('url = <nowiki></nowiki>','url = <nowiki>' + url2 + '</nowiki>')
			uploadFile(outputFolder + os.sep + finalREDImageName, finalREDImageName, description, wikiUsername, wikiPassword, category='', overwrite=False)
			uploadFile(outputFolder + os.sep + finalBLUImageName, finalBLUImageName, description2, wikiUsername, wikiPassword, category='', overwrite=False)
		else:
			finalImageName = itemName + ' 3D.jpg'
			url = fileURL(finalImageName)
			description = open(outputFolder + os.sep + finalImageName + ' offsetmap.txt', 'rb').read()
			description = description.replace('url = <nowiki></nowiki>','url = <nowiki>' + url + '</nowiki>')
			uploadFile(outputFolder + os.sep + finalImageName, finalImageName, description, wikiUsername, wikiPassword, category='', overwrite=False)
	# All done yay
	print '\nAll done'