#!BPY
# -*- coding: latin-1 -*-
"""Registration info for Blender menus
Name: 'Vertex Noise'
Blender: 2.48	
Group: 'Mesh'
Tip: 'add some random distortion to a selected mesh'
"""	

__author__ = "Sammler Rene"
__url__ = ("http://www.blender.org", "http://www.sammler-mediengestaltung.com")
__version__ = "v070507"

__bpydoc__ = """\
***** BEGIN GPL LICENSE BLOCK *****

This program is free software; you can redistribute it and/or<br>
modify it under the terms of the GNU General Public License<br>
as published by the Free Software Foundation; either version 2<br>
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 *****
--------------------------------------------------------------------------

This script allows to distort the selected vertex points along the specified directions.
"""

import Blender
from Blender.Draw import *
from Blender.BGL import *
from Blender.Object import *
from Blender.NMesh import *
from Blender.Window import *
from Blender.Types import *
from Blender.Mathutils import *
from random import *


def ExportConfig():
	conf = {}
	
	conf["X"] = tgl_x.val
	conf["Y"] = tgl_y.val
	conf["Z"] = tgl_z.val
	conf["LOC"] = tgl_local.val
	conf["GLOB"] = tgl_global.val
	conf["NORM"] = tgl_normal.val
	conf["ZERO_1"] = set_zero_1.val		
	conf["ZERO_2"] = set_zero_2.val	
	
	conf["MIN"] = min.val
	conf["MAX"] = max.val
	conf["R_SEED"] = r_seed.val
		
	Blender.Registry.SetKey("VERTEXNOISE", conf, True)

def ImportConfig():
	global tgl_x, tgl_y, tgl_z, min, max, r_seed,set_zero_1,set_zero_2,tgl_global,tgl_local,tgl_normal
	
	conf = Blender.Registry.GetKey("VERTEXNOISE", True)
	
	if not conf:
		return
	
	try:
		tgl_x.val=conf["X"]  
		tgl_y.val=conf["Y"]  
		tgl_z.val=conf["Z"] 
		tgl_local.val=conf["LOC"]  
		tgl_global.val=conf["GLOB"]  
		tgl_normal.val=conf["NORM"]  
		set_zero_1.val=conf["ZERO_1"]  
		set_zero_2.val=conf["ZERO_2"]  	
		
		min.val=conf["MIN"]  
		max.val=conf["MAX"]  
		r_seed.val=conf["R_SEED"]  
	except KeyError:
		pass
	
def type_check(obj_list):
	global failur
	ret = 0
	if len(obj_list) == 0: 
		failur = "ERROR: Select a Meshobject!!"
		ret = 1
	elif type(obj_list[0].getData()) != NMeshType: 
		failur = "ERROR: Select a Meshobject!!"
		ret = 1
	else: failur = ""
	return ret
	
def calc_verts_global(vertex, direction, value, trans_mat):
	val = 0
	if vertex.sel:
		val = uniform(value[0], value[1])
		
		vec = Vector(direction)*val
		
		vec = vec * trans_mat

		vertex.co[0] = vec[0] + vertex.co[0]
		vertex.co[1] = vec[1] + vertex.co[1]
		vertex.co[2] = vec[2] + vertex.co[2]
		
def calc_verts_local(vertex, direction, value):
	val = 0
	if vertex.sel:
		val = uniform(value[0], value[1])
		
		vec = Vector(direction)*val

		vertex.co[0] = vec[0] + vertex.co[0]
		vertex.co[1] = vec[1] + vertex.co[1]
		vertex.co[2] = vec[2] + vertex.co[2]		

def calc_verts_normal(vertex, value):
	val = 0
	if vertex.sel:
		val = uniform(value[0], value[1])
		
		vec = vertex.no*val

		vertex.co[0] = vec[0] + vertex.co[0]
		vertex.co[1] = vec[1] + vertex.co[1]
		vertex.co[2] = vec[2] + vertex.co[2]

				
def Event(evt, val):
	if evt == QKEY:
		ExportConfig()
		Exit()
		return

def BEvent(evt):
	global tgl_x, tgl_y, tgl_z, min, max, r_seed,set_zero_1,set_zero_2,tgl_global,tgl_local,tgl_normal
	
	if evt == 11:
		if type_check(Blender.Object.GetSelected()) == 0:
			edit_mode = EditMode()
			if EditMode(): EditMode(0)
			obj_lst = Blender.Object.GetSelected()
			if len(obj_lst) > 0:
				mesh = Blender.NMesh.GetRawFromObject(obj_lst[0].name)
				if r_seed.val > 0: seed(r_seed.val)
	
				intervall = [min.val,max.val]
				if set_zero_1.val: intervall[0] = 0.0
				if set_zero_2.val: intervall[1] = 0.0
							
				if tgl_global.val:
					zero_matrix = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]) 
					obj_matrix = Matrix(obj_lst[0].getMatrix())
					obj_matrix[3] = [0,0,0,1]
					transform_matrix = obj_matrix.invert() * zero_matrix
					[calc_verts_global(vertex, [tgl_x.val,tgl_y.val,tgl_z.val],intervall,transform_matrix) for vertex in mesh.verts]
				elif tgl_local.val:
					[calc_verts_local(vertex, [tgl_x.val,tgl_y.val,tgl_z.val],intervall) for vertex in mesh.verts]				
				else:
					[calc_verts_normal(vertex,intervall) for vertex in mesh.verts]				
				
				Blender.NMesh.PutRaw(mesh, mesh.name)
					
			if edit_mode: EditMode(1)		
	elif evt == 10:
		ExportConfig()
		Exit()
		return
	elif evt == 12:
		min.val = min.val * -1
	elif evt == 13:
		max.val = max.val * -1		
	elif evt == 14:
		min.val = max.val
	elif evt == 15:
		max.val = min.val	
	elif evt == 6:
		if tgl_global.val == 0:
			tgl_global.val = 1
		else:
			tgl_local.val = 0
			tgl_normal.val = 0
	elif evt == 7:
		if tgl_local.val == 0:
			tgl_local.val = 1
		else:
			tgl_global.val = 0
			tgl_normal.val = 0
	elif evt == 8:
		if tgl_normal.val == 0:
			tgl_normal.val = 1
		else:
			tgl_global.val = 0
			tgl_local.val = 0
			tgl_x.val = 0	
			tgl_y.val = 0
			tgl_z.val = 0
	elif evt == 1:
		if tgl_normal.val == 1:
			tgl_x.val = 0
	elif evt == 2:
		if tgl_normal.val == 1:
			tgl_y.val = 0
	elif evt == 3:
		if tgl_normal.val == 1:
			tgl_z.val = 0		
	
	Blender.Redraw()
	
def GUI():
	global tgl_x, tgl_y, tgl_z, min, max, r_seed,set_zero_1,set_zero_2, tgl_global, tgl_local, tgl_normal, failur
	
	glColor3f(0.7, 0.7, 0.7)
	glRecti(15, 50, 205, 255)	
	glColor3f(0.9, 0.9, 0.9)
	glRecti(15, 30, 205, 50)
	glColor3f(0.65, 0.65, 0.65)	
	glRecti(15, 255, 205, 275)
	glColor3f(0.0,0.0,0.0)
	glRasterPos2f(20,262)		
	Text("Vertex Noise (v 07 05 07)")		

	tgl_global = Toggle("Global", 6, 20, 230, 60, 20, tgl_global.val, "distort to global coordinates")
	tgl_local = Toggle("Local", 7, 80, 230, 60, 20, tgl_local.val, "distort to local coordinates")
	tgl_normal = Toggle("Normal", 8, 140, 230, 60, 20, tgl_normal.val, "distort to the vertex normals")

	min = Number("Min: ", 0, 20, 205, 100, 20, min.val, -100.0, 100.0, "the minimal distortion")
	
	neg_1 = Button("neg", 12, 20, 180, 60, 20, "negate the min value")
	cop_1 = Button("= max", 14, 80, 180, 60, 20, "copy the max value to min")
	set_zero_1 = Toggle("use 0", 4, 140, 180, 60, 20, set_zero_1.val, "use 0 insted the inserted min value")
	
	max = Number("Max: ", 0, 20, 155,100, 20, max.val, -100.0, 100.0, "the maximal distortion")
	
	neg_2 = Button("neg", 13, 20, 130, 60, 20, "negate the max value")
	cop_2 = Button("= min", 15, 80, 130, 60, 20, "copy the min value to max")
	set_zero_2 = Toggle("use 0", 5, 140, 130, 60, 20, set_zero_2.val, "use 0 insted the inserted max value")
	
	r_seed = Number("Seed: ", 0, 20, 105,110, 20, r_seed.val, -100.0, 100.0, "")

	tgl_x = Toggle("X", 1, 20, 80, 60, 20, tgl_x.val, "distort to x direction")
	tgl_y = Toggle("Y", 2, 80, 80, 60, 20, tgl_y.val, "distort to y direction")
	tgl_z = Toggle("Z", 3, 140, 80, 60, 20, tgl_z.val, "distort to z direction")
	
	quit = Button("Quit", 10, 20, 55, 80, 20, "")
	ok = Button("OK", 11, 120, 55, 80, 20, "")
	
	glColor3f(0.15, 0.15, 0.15)
		
	glRasterPos2f(150,210)
	Text(str(min.val)[0:6])

	glRasterPos2f(150,160)
	Text(str(max.val)[0:6])

	glRasterPos2f(150,110)
	Text(str(r_seed.val)[0:6])	
		
	glRasterPos2f(105,20)	
	Text("created by Rene Sammler", "tiny")
	glRasterPos2f(75,12)	
	Text("(sammler-mediengestaltung.com)", "tiny")
	glRasterPos2f(150,4)	
	Text("(v 07 05 07)", "tiny")
	glColor3f(1, 0.0, 0.0)
	glRasterPos2f(20,35)	
	Text(failur)	

tgl_x = Create(0)
tgl_y = Create(0)
tgl_z = Create(0)
tgl_local = Create(1)
tgl_global = Create(0)
tgl_normal = Create(0)
set_zero_1 = Create(0)
set_zero_2 = Create(0)
failur = ""

min = Create(0.0000)
max = Create(0.0000)
r_seed = Create(0.0000)

ImportConfig()
Register(GUI, Event, BEvent)