#!BPY
"""
Name: 'Dynamic Framebased Texture Changer'
Blender: 248
Group: 'Materials'
Tooltip: 'Edit the values in the script below in the section User Definable Variables to work'
"""

#__author__ = "Holly Tsukiko Grimes"
#__url__ = ["http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Materials/Frame_Tex_Changer"]
#__version__ = "0.8"
#__bpydoc__ = """\
#Description:

# This script is a texture changer in any animation. This accesses the textures in a materials
#channels and changes the texture in that channel depending on the frame number. 
#
# This is perfect for animations using textures. This could be adapted for Games easily by 
#incorporating the script to run from commands.. i.e, you could have it so that when a character
#'talks' in game, it would run a precompiled sequence of textures from this easily. This could
#be adapted for editing UV maps easily.
#
# Currently this is built in such a way that you need to have Textures set up prior to this script
#as this would do better for gaming and such and you dont need to reload images from files, but instead
#from memory. This does mean a little bit of setup time, but the code could be easily changed that instead
#of switching textures, you can change the filename instead the base texture and reload.
#
# I added in the feature that you can animate more than 1 object at a time, you just need to fill
#out the list correctly with more lists of channels, which is easy. 
#
# This was built out of a need to easily and quickly change textures on a material on certain
#frames, in particular for a face composed of channels with a channel for eyes, a channel for
#the mouth, 1 for eyebrows, etc.
#
# Updates since version 0.7:
# Corrected a glitch in the code which selects a channel.
#
#
# Limitations of this version:
# The channels need to be preoccupied in a material first for this to work, but, you dont need
#to have all the channels filledto use the script, only the ones you need to change need to
#have something in there first.
#
# Only allows you to change the 9 channels on a single material so far, which i guess is
#already the limit in blender per material anyway, so it doesnt matter.
#
# There seems to be a flaw in Blender that the script doesnt change using a FrameChanged link
#unless the material tab is open using Alt-A and having blender game GLSL materials active.
#This still works using Anim, previewing requires the material panel open for this to work.

#Usage:
#Edit the channel information below. examples are given above the channels. There is no limit i believe
#on how many changes you can put for a channel.
#"""

#Script: Dynamic Framebased Texture Changer
#Date:  07/02/08
#Version 0.8
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) Holly Tsukiko Grimes
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
import Blender
from Blender import *

######################################################
#User Definable Variables
#Edit these names for your own objects.
######################################################

#Objects, Materials, Textures and the details needed to change the texture over time.

#Here are 2 examples, these are useable if you just take out the leading hashes.


#Example 1: 
#1 object being changed called "TNenfaceTex"(a face as you can tell), 1 material being
#changed called "TToonSkinTex1" in the object (not necessarily material 1 in the object, the materials
#are all searched in the object). 4 channels are being used in this material, only 2 are animated
#with something. 
#
#channels 1 and 6-10 are either non-animated textures or empty in the material.
#
#channel 2's texture uses the texture "TFaceNoseBase" for the all of the animation. This
#doesn't change.
#
#channel 3's texture uses the texture "TFaceMouthBase" for the bulk of the animation. This
#changes to "TFaceMouthSmirk" at frame 100 for 10 frames (until frame 110). At frame 110, it
#changes back to the base texture "TFaceMouthBase" and stays that way until the end of the animation.
#
#channel 4's texture uses the texture "TFaceEyesBase" for the bulk of the animation. 
#This changes to "TFaceEyesHalfopen" at frame 25 for 5 frames (until frame 30). 
#At frame 30, it changes to the texture "TFaceEyesClosed" for 10 frames (until frame 40).
#At frame 40, it changes back to "TFaceEyesHalfopen" for 5 frames until frame 45.
#At frame 45, it changes back to the base texture "TFaceEyesBase" until the next change (at frame 75
#as seen in this example). This channel creates several 'blink' style animations easily.
#
#channel 5's texture uses the texture "TFaceEyeBBase" for the all of the animation. This
#doesn't change.
#
#Code:
#
#MaterialChannels=[
#[["TNenfacetex","TToonSkinTex1"],
#[["",1]],
#[["TFaceNoseBase",2]], 
#[["TFaceMouthBase",3],["TFaceMouthSmirk",100,10]],
#[["TFaceEyesBase",4],["TFaceEyesHalfopen",25,5,35,5,75,5,85,5,115,5,125,5],["TFaceEyesClosed",30,10,80,10,120,10]],
#[["TFaceEyeBBase",5]],
#[["",6]],
#[["",7]],
#[["",8]],
#[["",9]],
#[["",10]]]]


#Example 2: 
#2 objects are being changed. first is called "TNenfaceTex"(a face as you can tell), 1 material being
#changed called "TToonSkinTex1" in the object (not necessarily material 1 in the object, the materials
#are all searched in the object). 4 channels are being used in this material, only 2 are animated
#with something. channels 1 and 6-10 are either non-animated textures or empty in the material.
#This first material animation is identical to above.
#Object 2 is called "TNenHair", of which 1 material is changed called "TNenHairMaterial". In this
#material 2 channels are being animated, channels 3-10 are not being used.
#
#channel 1's texture uses the texture "THairFringeBaseTex" for the bulk of the animation. This
#changes to "THairFringeShinyTex" at frame 200 for 50 frames (until frame 250). At frame 700, it
#changes to "THairFringeDullTex" for 600 frames (until frame 1300).
#
#channel 2's texture uses the texture "THairLongHairBaseTex" for the bulk of the animation. This
#changes to "THairLongHairShinyTex" at frame 200 for 50 frames (until frame 250). At frame 700, it
#changes to "THairLongHairDullTex" for 600 frames (until frame 1300).
#
#Code:
#
#MaterialChannels=[
#[["TNenfacetex","TToonSkinTex1"],
#[["",1]],
#[["TFaceNoseBase",2]], 
#[["TFaceMouthBase",3],["TFaceMouthSmirk",100,10]],
#[["TFaceEyesBase",4],["TFaceEyesHalfopen",25,5,35,5,75,5,85,5,115,5,125,5],["TFaceEyesClosed",30,10,80,10,120,10]],
#[["TFaceEyeBBase",5]],
#[["",6]],
#[["",7]],
#[["",8]],
#[["",9]],
#[["",10]]],
#[["TNenHair","TNenHairMaterial"],
#[["THairFringeBaseTex",1],["THairFringeShinyTex",200,50],["THairFringeDullTex",700,600]],
#[["THairLongHairBaseTex",2],["THairLongHairShinyTex",200,50],["THairLongHairDullTex",700,600]], 
#[["",3]],
#[["",4]],
#[["",5]],
#[["",6]],
#[["",7]],
#[["",8]],
#[["",9]],
#[["",10]]]]

MaterialChannels=[
[["TNenfacetex","TToonSkinTex1"],
[["",1]],
[["TFaceNoseBase",2]],
[["TFaceMouthBase",3],["TFaceMouthSmirk",100,10]],
[["TFaceEyesBase",4],["TFaceEyesHalfopen",25,5,35,5,75,5,85,5,115,5,125, 5],["TFaceEyesClosed",30,10,80,10,120,10]],
[["TFaceEyeBBase",5]],
[["",6]],
[["",7]],
[["",8]],
[["",9]],
[["",10]]]]

######################################################
#function
# change the Textures based on the current frame
######################################################

import Blender
def main():

	global MaterialChannels
	MatIndex=-10

	scn= Blender.Scene.GetCurrent()
	frame=str(Blender.Get('curframe'))

	#find material index of the object
	for Onum in range (0,len(MaterialChannels)):
		FaceObj = Blender.Object.Get(MaterialChannels[Onum][0][0])
		#FaceObj.select(1)
		MatList = FaceObj.getData().getMaterials()
		if MatIndex < 0:
			for mnum in range(0,len(MatList)-1):
				if MatList[mnum].getName() == MaterialChannels[Onum][0][1]:
					MatIndex=mnum
		MatFace=MatList[MatIndex]
		TexSlotList = MatFace.getTextures()


		#channels
		for Cnum in range(1,11):
			if len(MaterialChannels[Onum][Cnum])>1:		
				channelTex=TexSlotList[Cnum-1]
				channeltexBase = Blender.Texture.Get(MaterialChannels[Onum][Cnum][0][0])  
				channelTex.tex = channeltexBase
				for Lnum in range(1, len(MaterialChannels[Onum][Cnum])):
					for Fnum in range(0,(len(MaterialChannels[Onum][Cnum][Lnum])-1)/2):
						if int(frame) in range(MaterialChannels[Onum][Cnum][Lnum][1+(Fnum*2)],MaterialChannels[Onum][Cnum][Lnum][1+(Fnum*2)]+MaterialChannels[Onum][Cnum][Lnum][2+(Fnum*2)]):
							channelTex.tex = Blender.Texture.Get(MaterialChannels[Onum][Cnum][Lnum][0])
main()