#!BPY
""" Released under the Blender Artistic Licence (BAL)
Name: 'Vertcol 2 Heightmap'
Blender: 235
Group: 'Object'
Submenu: 'Update active object' update
Submenu: 'Show GUI' gui
Tooltip: 'Use a meshs vertex color as heightmap'
"""
__author__ = "pat"
__version__ = "1.3b - 01/10/05 -"
__email__ = ('Author, pat:psycho3d*de')
__url__ = ("Author's website, www.psycho3d.de")
__bpydoc__ ="""\
This script modifies each verts z coordinate depending on the vertex color.

When starting, the script offers to update the active object immediately
using the red vertex color, or to show the GUI

The script uses the vertex color to set each verts z coordinate
to a value between 0 and 1.<br>
I assume that heightmaps are greyscale, but you may use the two unused
colors for whatever you like since you can select which color to use.

You will have to scale the object's z axis after applying the heightmap.

Buttons:<br>
   Select Object: Change the script's active object.<br>
   Update Mesh: Apply the selected color as heightmap.<br>
   Flatten Mesh: Reset the mesh to a flat plane, might be easier to edit vertcols.

Hotkeys:<br>
   Q: [Q]uit
"""

from Blender.Object import GetSelected
from Blender.Draw import *
from Blender.BGL import *
from Blender.Window import Theme

colmenu = Create(0)
message = ""
ob = None

##############################
#select active object
def getObject():
  global ob, message
  try:
    ob = None #to avoid errors
    ob = GetSelected()[0]
    if ob.getType() == "Mesh":
      message = "The script now works on: %s" % ob.name
    else:
      message = "Active object is not a mesh! Select a mesh and click \"Select Object\"."
      ob = None
  except IndexError:
    message = "No object active! Select a mesh and click \"Select Object\"."
  Redraw()

##############################
def UpdateHeight():
  global ob, message
  if ob == None:
    message = "No object active! Select a mesh and click \"Select Object\"."
  else:
    #first update our mesh to current status
    me = ob.getData()
    facelist = me.faces
    message = "Updated"
    for f in facelist:
      collist = []
      if colmenu.val == 2:
        for color in f.col:
          collist.append(color.b)
      elif colmenu.val == 1:
        for color in f.col:
          collist.append(color.g)
      else:
        for color in f.col:
          collist.append(color.r)
      try:
        f.v[0].co.z = collist[0] / 255.0
      except IndexError:
        message = "Error: mesh has no vertex colors!"
      else:
        f.v[1].co.z = collist[1] / 255.0
        try: #for edges & tris
          f.v[2].co.z = collist[2] / 255.0
          f.v[3].co.z = collist[3] / 255.0
        except IndexError:
          pass
    me.update()
    Redraw()

def flatten():
  global ob, message
  if ob == None:
    message = "No object active! Select a mesh and click \"Select Object\"."
  else:
    me = ob.getData()
    facelist = me.faces
    message = "Flattened"
    for f in facelist:
      f.v[0].co.z = 0
      f.v[1].co.z = 0
      f.v[2].co.z = 0
      try:
        f.v[3].co.z = 0
      except IndexError:
        pass
    me.update()
    Redraw()

def gui():
  global colmenu
  col = Theme.Get()[0].get("buts").back
  glClearColor(col[0]/255., col[1]/255., col[2]/255., col[3]/255.)
  glClear(GL_COLOR_BUFFER_BIT)
  col = Theme.Get()[0].get("buts").text_hi
  glColor3f(col[0]/255., col[1]/255., col[2]/255.)
  name = "Color to use%t|Red%x0|Green%x1|Blue%x2"
  colmenu = Menu(name, 2, 10, 150, 100, 20, colmenu.val, "Just a test menu.")
  Button("Exit", 1, 10, 10, 100, 20, "This one should explain itself :)")
  Button("Select Object", 5, 10, 60, 100, 20, "Change the object the script works on")
  Button("Update Mesh", 3, 10, 112, 100, 28, "Change the verts z coordinate depending on vertex color")
  Button("Flatten Mesh", 4, 10, 90, 100, 20, "Reset the verts z coordinate to 0")
  glRasterPos2i(10, 40)
  Text(message)

def event(evt, val):
  if (evt == QKEY and not val): Exit()

def bevent(evt):
  if (evt == 1): Exit()
  elif (evt == 3): UpdateHeight()
  elif evt == 4: flatten()
  elif (evt == 5): getObject()

getObject()
arg = __script__['arg']
if arg == 'update':
  if message == "No object active! Select a mesh and click \"Select Object\".":
    PupMenu("Error%t|There is no active mesh object.")
  elif message == "Active object is not a mesh! Select a mesh and click \"Select Object\".":
    PupMenu("Error%t|The active object is not a mesh.")
  else:
    UpdateHeight()
else:
  Register(gui, event, bevent)

