#!BPY
"""
Name: 'Fiber Plugin'
Blender: 248
Group: 'Wizards'
Tip: 'Create Mesh Grass.'
"""

__author__ = "Alan Dennis (RipSting) "
__url__ = ("blender", "blenderartists.org")
__version__ = "248"

__bpydoc__ = """\
This script creates mesh grass
Usage:

Open it from Wizards Menu
"""
#Fiber Generator V2.03 - May 24th, 2004
#Created by Alan Dennis (RipSting)
#dennisa@onid.orst.edu
#_________________________________________________
#Special thanks to Alfredo de Greef (Eeshlo) for
#providing the DyNoise module and the multmat
#and renormal subroutines!!!
#Thanks goes out to Peter De Bock for
#fixing the vertex color problems!!!
#_________________________________________________



#--------------I N F O R M A T I O N--------------
#READ THE README FILE!!!!!!!!
#
#Make sure all files are extracted to the same folder
#and then hit Alt-P with your curson in this window
#to run the script!
#
#You must have at least one mesh object selected.
#You may select multiple mesh objects for the script
#to run on, but one must have primary focus (a lighter
#pink color) OR THE SCRIPT WILL CRASH BLENDER!!!
#
#IMPORTANT NOTE:
#and press Ctrl-L -> Materials.  BUT THIS CAN ALSO
#CRASH BLENDER!  SAVE FIRST!!!



#_________________________________________________
#Start of Script
#_________________________________________________
import os
import Blender
from Blender import NMesh, Object
from Blender.BGL import *
from Blender.Draw import *
from string import strip
from Fiber2 import RunFiber, random, fncArea, ControlPoints
seed = 1
CurVersion = "2.03"

sldDensity  = Create(5.0)
sldGravity  = Create(2.0)
sldSegments = Create(3)
sldLength   = Create(5.0)
sldSegRand	= Create(0.0)
sldWidth    = Create(3.0)
sldInit     = Create(0.0)
sldRand     = Create(5.0)
sldRloc     = Create(0.0)
sldFollow   = Create(1.0)
sldFalloff	= Create(2.0)
sldControl 	= Create(10)
sldCtrlSeg	= Create(4)


txtDensity  = Create(50)
txtGravity  = Create(20)
txtSegments = Create(20)
txtLength   = Create(50)
txtWidth    = Create(20)
txtInit     = Create(50)
txtRand     = Create(50)
txtRloc     = Create(50)
txtFalloff  = Create(10)


chkPointed  = Create(0)
chkVCol     = Create(0)
chkWind     = Create(0)
chkGuides	= Create(0)


#Get the current path and filename
a = Blender.Get("filename")
b = Blender.sys.dirname(a)
a = a.split(os.sep)[len(a.split(os.sep)) -1]
fname = b + os.sep + str(a.split(".")[0]) + ".fib"

txtFile     = Create(fname)
txtFaces    = Create("Click 'Estimate Faces'")

txtFollowtext = "Follow Normals / Z-Axis"

BL_VERSION = Blender.Get('version')
if BL_VERSION<=223:
	# <=2.23 need Blender210 module to get current camera etc.
	# as well as the convenient GUI fileselector
	import Blender210, GUI
	FSEL = GUI.FileSelector()
else:
	from Blender import Window


def draw():
	global sldDensity, sldGravity, sldSegments, sldLength, sldWidth, sldInit
	global sldRand, sldRloc, sldFollow, sldControl, sldCtrlSeg, sldSegRand, sldFalloff
	global txtDensity, txtGravity, txtSegments, txtLength, txtWidth, txtInit
	global txtRand, txtRloc, txtSegRand, txtFalloff
	global chkPointed, chkVCol, chkWind, chkGuides
	global txtFile, txtFaces

	glClearColor(.7, .7, .7, 0.0)
	glClear(GL_COLOR_BUFFER_BIT)
	glColor3f(0,0.528,0.990)
	glRasterPos2i(30, 410)
	Text("RipSting's Fiber Generator-  Version " + CurVersion)
	glColor3f(0,0,0)
	glRasterPos2i(400, 410)
	Text("Max")	

	Button("Estimate Faces", 90,  30,  10, 100, 35)
	Button("Create",         95, 350,  10,  75, 35)
	Button("Select ",        96,  30, 430,  50, 18)
	Button("Save Preset",    97,  30, 450, 100, 25)
	Button("Load Preset",    98, 150, 450, 100, 25)
	Button("Exit",           99, 355, 450,  75, 25)
	Button("Make",			 91, 390,  80,  40, 19)
	

	txtFile     = String("", 80, 90, 430, 340, 18, txtFile.val, 399) 
	txtFaces    = String("", 81, 140, 20, 200, 18, txtFaces.val, 45) 

	chkPointed  = Toggle("Pointed" ,70,30,50,75,25 ,chkPointed.val)
	chkVCol	 	= Toggle("Use VCol",71,123,50,75,25,chkVCol.val)
	chkWind		= Toggle("Use Wind",72,215,50,75,25,chkWind.val)
	chkGuides	= Toggle("Use Guides",73,306,50,75,25,chkGuides.val)

	txtDensity  = Number("",50, 390, 380, 40, 19, txtDensity.val, 1,1000)
	txtSegments = Number("",52, 390, 355, 40, 19, txtSegments.val, 1,1000)
	txtLength   = Number("",53, 390, 330, 40, 19, txtLength.val, 1,1000)
	txtWidth    = Number("",54, 390, 280, 40, 19, txtWidth.val, 1,1000)
	txtGravity  = Number("",51, 390, 255, 40, 19, txtGravity.val, -999,1000)
	txtInit     = Number("",55, 390, 230, 40, 19, txtInit.val, 1,1000)
	txtRand     = Number("",56, 390, 205, 40, 19, txtRand.val, 1,1000)
	txtRloc     = Number("",57, 390, 180, 40, 19, txtRloc.val, 1,1000)
	txtFalloff	= Number("",58, 390, 130, 40, 19, txtFalloff.val, 0,1000)

	sldDensity  = Slider("Density                       ",  2, 30, 380, 351, 18, sldDensity.val, 0.0, txtDensity.val,0)
	sldSegments = Slider("Segments                    ",    4, 30, 355, 351, 18, sldSegments.val, 1.0, txtSegments.val,0)
	sldLength   = Slider("Length of Segment        ",       5, 30, 330, 351, 18, sldLength.val, 0.0, txtLength.val,0)
	sldSegRand  = Slider("Randomize Length %     ",     	13,30, 305, 351, 18, sldSegRand.val, 0.0, 1.0,0)
	sldWidth    = Slider("Width                          ", 6, 30, 280, 351, 18, sldWidth.val, 0.0, txtWidth.val,0)
	sldGravity  = Slider("Gravity                        ", 3, 30, 255, 351, 18, sldGravity.val, 0.0, txtGravity.val,0)
	sldInit     = Slider("Initial Gravity                ", 7, 30, 230, 351, 18, sldInit.val, 0.0, txtInit.val,0)
	sldRand     = Slider("Randomize Direction     ",        8, 30, 205, 351, 18, sldRand.val, 0.0, txtRand.val,0)
	sldRloc     = Slider("Frizziness                    ",  9, 30, 180, 351, 18, sldRloc.val, 0.0, txtRloc.val,0)
	sldFollow   = Slider("Normals / Clumpiness    ",       10, 30, 155, 351, 18, sldFollow.val, 0.0, 1.0,0)
	sldFalloff	= Slider("Clumpiness Falloff         ",	   14, 30, 130, 351, 18, sldFalloff.val, 0.0, txtFalloff.val,0)
	sldControl	= Slider("Fiber Guides                ",   11, 30, 105, 351, 18, sldControl.val, 3.0, 100,0)
	sldCtrlSeg  = Slider("Fiber Guide Segments    ",   	   12, 30, 80,  351, 18, sldCtrlSeg.val, 3.0, 4,0)

def event(evt, val):	
	if (evt== QKEY and not val): Exit()

def bevent(evt):
	if evt == 99: #Exit
		Exit()
	elif evt == 72: #Use Wind
		if chkWind.val == 1:
			try:
				Wind = Object.Get("Wind")
				test = Wind.LocY
			except:
				Wind = Object.New(Object.Types.EMPTY)
				Wind.name = "Wind"

				Wind.LocX = 0.0
				Wind.LocY = 0.0
				Wind.LocZ = 0.0
				Wind.RotX = 0.0
				Wind.RotY = 0.0
				Wind.RotZ = 0.0

				Blender.Redraw()
	#elif evt == 73: #Check Fiber Guides
	#	if chkGuides.val == 0:
	#		txtFollowtext = "Normals / Clumpiness"
	#	else:
	#		txtFollowtext = "Clumpiness"
	#	txtFaces.val = txtFollowtext
	#	draw()
	elif evt == 96: #File Selector
		if BL_VERSION <= 223:
			FSEL.activate(callback)
		elif BL_VERSION >= 228:
			Window.FileSelector (callback228, "Select a .fib preset!")
	elif evt == 97: #Save Preset
		SavePreset(txtFile.val)
	elif evt == 98: #Load Preset
		LoadPreset(txtFile.val)
	elif evt == 95: #Create!
		SavePreset(fname)
		RunFiber()
	elif evt == 90: #Estimate Faces
		faces = 0
		object = Object.GetSelected()
		mat = object[0].matrix
		for num in range(len(object)):
			if BL_VERSION<=223:
				original = object[num].data
			else:
				original = object[num].getData()
			
			for fa in original.faces:
				faces += (int(fncArea(fa,mat) * sldDensity.val))
		txtFaces.val = str(faces *2) + " faces predicted"
		print str(faces *2) + " faces predicted"
	elif evt == 91: #Creat Fiber Guides
		ControlPoints (sldControl.val, sldCtrlSeg.val)
		
	Blender.Redraw()

def callback():
	txtFile.val = FSEL.filename
	Register(draw, event, bevent)

def callback228(filename):
	txtFile.val = filename
	Register(draw, event, bevent)

def writeln(f,x):
  f.write(str(x))
  f.write("\n")

def readint(f):
  return int(f.readline())

def readfloat(f):
  return float(f.readline())

def readstr(f):
  s = (f.readline())
  return strip(s)

def SavePreset(FName):
	global sldDensity, sldGravity, sldSegments, sldLength, sldWidth, sldInit
	global sldRand, sldRloc, sldFollow, sldControl, sldCtrlSeg, sldSegRand, sldFalloff
	global txtDensity, txtGravity, txtSegments, txtLength, txtWidth, txtInit
	global txtRand, txtRloc, txtFalloff
	global chkPointed, chkVcol, chkWind, chkGuides

	try:
		f = open(FName,'w')
	except:
		message = "unable to save file."
		return
	
	writeln(f,CurVersion)
	
	writeln(f,sldDensity.val)
	writeln(f,sldGravity.val)
	writeln(f,sldSegments.val)
	writeln(f,sldLength.val)
	writeln(f,sldWidth.val)
	writeln(f,sldInit.val)
	writeln(f,sldRand.val)
	writeln(f,sldRloc.val)
	writeln(f,sldFollow.val)
	writeln(f,sldControl.val)
	writeln(f,sldCtrlSeg.val)
	writeln(f,sldSegRand.val)
	writeln(f,sldFalloff.val)
	writeln(f,txtDensity.val)
	writeln(f,txtGravity.val)
	writeln(f,txtSegments.val)
	writeln(f,txtLength.val)
	writeln(f,txtWidth.val)
	writeln(f,txtInit.val)
	writeln(f,txtRand.val)
	writeln(f,txtRloc.val)
	writeln(f,txtFalloff.val)
	writeln(f,chkPointed.val)
	writeln(f,chkVCol.val)
	writeln(f,chkWind.val)
	writeln(f,chkGuides.val)
	writeln(f,int(random()*1000))
	writeln(f,1) #First Run
	object = Object.GetSelected()
	for z in range(len(object)):
		writeln(f,object[z].name)
	f.close()

def LoadPreset(FName):
	global sldDensity, sldGravity, sldSegments, sldLength, sldWidth, sldInit
	global sldRand, sldRloc, sldFollow, sldControl, sldCtrlSeg, sldSegRand, sldFalloff
	global txtDensity, txtGravity, txtSegments, txtLength, txtWidth, txtInit
	global txtRand, txtRloc, txtFalloff
	global chkPointed, chkVcol, chkWind, chkGuides

	try:
		f = open(FName,'r')
	except:
		message = "unable to open preset."
		return
	
	FVersion = readfloat(f)
	
	sldDensity.val  = readfloat(f)	
	sldGravity.val  = readfloat(f)
	sldSegments.val = readint(f)
	sldLength.val   = readfloat(f)
	sldWidth.val    = readfloat(f)
	sldInit.val     = readfloat(f)
	sldRand.val     = readfloat(f)
	sldRloc.val     = readfloat(f)
	sldFollow.val   = readfloat(f)
	sldControl.val 	= readfloat(f)
	sldCtrlSeg.val  = readfloat(f)
	sldSegRand.val	= readfloat(f)
	sldFalloff.val	= readfloat(f)
	txtDensity.val  = readint(f)
	txtGravity.val  = readint(f)
	txtSegments.val = readint(f)
	txtLength.val   = readint(f)
	txtWidth.val    = readint(f)
	txtInit.val     = readint(f)
	txtRand.val     = readint(f)
	txtRloc.val     = readint(f)
	txtFalloff.val	= readint(f)
	chkPointed.val  = readint(f)
	chkVCol.val     = readint(f)
	chkWind.val     = readint(f)
	chkGuides.val	= readint(f)
	f.close()
Register(draw, event, bevent)
LoadPreset (fname)