#!BPY
"""
Name: 'Armature Modeler'
Blender: 248
Group: 'Animation'
Tooltip: 'Makes a mesh proxy from selected armature'
"""
__author__ = ["malefico"]
__url__ = ("http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Animation/Armature_Modeler")
__version__ = "0.2 - 03.07.2007"

__bpydoc__ = """\
This script basically Makes the armature real so you can render it.

You can also use other objects to cover the armature.

"""

# Add a licence here if you wish to re-distribute, we recommend the GPL

 #  ***** BEGIN GPL LICENSE BLOCK *****
 #
 #  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 3 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, see <http://www.gnu.org/licenses/>.
 #
 #  The Original Code is Copyright (C) <01>-<2009> by <malefico>	###
 #  All rights reserved.
 #
 #  Contact:      <name>@<domain.ext>	###
 #  Information:  http://<domain>.<ext>	###
 #
 #  The Original Code is: all of this file.
 #
 #  Contributor(s): none yet.
 #
 #  ***** END GPL LICENSE BLOCK *****

# Armature Modeller 0.1
# -------------------------------
# by malefico
# malefico@manosdigitales.com
#
# Creates and parent proxy geometry for all deforming bones selected.
# Default geometry resembles an octaedron bone. User can choose own custom geometry
# Function MakeOctaedron() creates an octaedron with the given Lenght. 
# Change it or replace it to generate own shapes.
#
# USAGE:
# -------
# Set Armature to Rest Pose.
# Select bones in edit/pose mode. 
# From object mode run script.
# If wiling to use custom geometry, be sure to set object center properly
# remember long bone axis is Y axis. 

import Blender
from Blender import *

menu_solidbone_menu = Draw.Create(1)
string_customob = Draw.Create("")
GEOM = "Octaedron"
CUSTOM = ""

def MakeOctaedron(L):
	editmode = Window.EditMode()    # are we in edit mode?  If so ...
	if editmode: Window.EditMode(0) # leave edit mode before getting the mesh
	
	# define vertices and faces for an octaedron
	
	D = 0.12	# distancia de semidiametro mayor del octaedro al extremo
	#L= 4.0	# longitud del hueso octaedro.
	coords=[ [0,0,0], [D, D, D], [D, D, -D], [-D, D, -D],[-D, D, D], [0,L,0]]
	#coords=[ [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1], [0,0,1] ]  
	faces= [ [0,1,2], [0,2,3], [0,3,4], [0,4,1], [5,1,2],[5,2,3],[5,3,4],[5,4,1] ]
	
	me = Mesh.New('Bone')          # create a new mesh
	
	me.verts.extend(coords)          # add vertices to mesh
	me.faces.extend(faces)           # add faces to the mesh (also adds edges)
	
	scn = Scene.GetCurrent()          # link object to current scene
	ob = scn.objects.new(me, 'BoneMesh')
	
	if editmode: Window.EditMode(1)  # optional, just being nice
	
	return ob

def MakeCustomBone(Ob, L):
	scn = Scene.GetCurrent()          # link object to current scene
	me = Ob.getData()
	ob = scn.objects.new(me, 'BoneMesh')
	return ob
#MakeOctaedron(12.0) # Makes a sample Octaedron

def LeeHuesos(GEOM, CUSTOM):
	scn= Scene.GetCurrent()
	arm_ob= scn.objects.active
	if not arm_ob or arm_ob.type != 'Armature':
		Draw.PupMenu('This is not an armature object')
		return
# Deselect all
	for ob in scn.objects:
		if ob != arm_ob:
			ob.sel= 0
	arm_mat= arm_ob.matrixWorld
	arm_data= arm_ob.getData()
	
	# transform list of bones into bonesdict
	bones_list= arm_data.bones.values()
	bones_dic = {}
	for a in bones_list:
		bones_dic[a.name] = a
	#
	pose = arm_ob.getPose().bones # pose take account final transforms
	print "pose",pose
	print "huesos", bones_list
 	for bone in pose.keys():
		bone_mat= pose[bone].poseMatrix#['ARMATURESPACE']
		bone_mat_world= bone_mat*arm_mat
		bone_len= bones_dic[bone].length
		#print bone_len
		if Blender.Armature.BONE_SELECTED in bones_dic[bone].options:
			if Blender.Armature.NO_DEFORM not in bones_dic[bone].options:
				print  bone, " es un hueso deformante",
				if GEOM == 'Octaedron':
					solid_bone = MakeOctaedron(bone_len)
					solid_bone.setMatrix(bone_mat_world)
					arm_ob.makeParentBone([solid_bone], bone)
				elif GEOM == 'Custom':
					# Creates object instance with proper size
					# Toma objeto custom y aplica escala Y = lenght
					custom_obj = Blender.Object.Get(CUSTOM)
					solid_bone = MakeCustomBone(custom_obj, bone_len)
					# Calculates custom object length in Y
					boundbox = solid_bone.getBoundBox()
					box_len= abs(boundbox[0][1] - boundbox[2][1])
					# Calculates ratio bone_length/custom_object_length
					SY = bone_len/box_len
					# Applies ratio to instance of custom object
					NewSXYZ = [solid_bone.SizeX, SY * solid_bone.SizeY, solid_bone.SizeZ]
					solid_bone.setMatrix(bone_mat_world)
					solid_bone.setSize(NewSXYZ)
					# Parent custom object to bone
					arm_ob.makeParentBone([solid_bone], bone)
	Blender.Window.RedrawAll()							
#def main():
#	GEOM = 'Custom'
#	LeeHuesos(GEOM)

def but_event(evt):
	global menu_solidbone_menu
	global string_customob
	global CUSTOM
	global GEOM

	if evt == 1000:
		print "You chose somehting from menu"
		print "Valor menu:", menu_solidbone_menu.val
		if menu_solidbone_menu.val == 1:
			GEOM = 'Octaedron'
			Draw.Redraw()
		elif menu_solidbone_menu.val ==2:
			GEOM = 'Custom'
			#string_customob = Draw.String('', 1001, 29, 39, 111, 21, string_customob.val, 128, 'Fill in name of custom shape')
			Draw.Redraw()
	elif evt == 1001:
		print "You filled in OB field"
		CUSTOM = string_customob.val
	elif evt == 1002:
		Draw.Exit()
	elif evt == 1003:
		print "You made it!"
		# Check if Custom object is filled in
		if GEOM == 'Custom':
			if CUSTOM <> "":
				LeeHuesos(GEOM,CUSTOM)
			else:
				PupBlock("Error", "No Custom Object defined")
		elif GEOM == 'Octaedron':
			LeeHuesos(GEOM, CUSTOM)
				
		

def input_event(evt, val):
	#print evt, val
	if evt == Draw.QKEY:
		Draw.Exit()
	#if evt == 1000:
	#	Draw.Redraw(1)
	pass
	
def draw_interface():
	global menu_solidbone_menu
	global string_customob
	global GEOM
	
	BGL.glColor3f(0,0,0)
	BGL.glRasterPos2d(10, 130)
	Draw.Text('by malefico')

	BGL.glRasterPos2d(9, 100)
	Draw.Text('Select Bone Type:')
	BGL.glRasterPos2d(10, 150)
	Draw.Text('Armature Modeler v0.1b')
	menu_name = "Bone Shape: %t|Octaedron %x1|Custom %x2"
	menu_solidbone_menu = Draw.Menu(menu_name, 1000, 29, 69, 110, 21, menu_solidbone_menu.val, 'Select shape for bone or Custom to choose your own shape')
	if GEOM == "Custom":
		BGL.glRasterPos2d(10, 50)
		Draw.Text('OB:')
		string_customob = Draw.String('', 1001, 29, 39, 111, 21, string_customob.val, 128, 'Fill in name of custom shape')
	Draw.PushButton('Exit', 1002, 99, 9, 40, 21, 'Leave now')
	Draw.PushButton('Make', 1003, 29, 9, 40, 21, 'Create Mesh Armature')


Draw.Register(draw_interface, input_event, but_event)

#main()