import math
from math import pi,sin,cos,atan,tan,fabs
import vefm
from vefm import *
from Blender import NMesh
class form(mesh):

	def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):

		mesh.__init__(self)

		self.a360=pi*2.0

		self.ures=uresolution
		self.vres=vresolution
		
		self.uscale=uscale
		self.vscale=vscale

		self.upart=upart
		self.vpart=vpart

		self.uphase=uphase*self.a360
		self.vphase=vphase*self.a360

		self.utwist=utwist
		self.vtwist=vtwist
		
		self.xscale=xscale
		self.yscale=yscale

		self.sform=sform
				
		if self.upart!=1.0:	## there is a gap in the major radius
			
			self.uflag=1
		else:
			self.uflag=0

		if self.vpart!=1.0:	## there is a gap in the minor radius
			
			self.vflag=1
		else:
			self.vflag=0

		if self.uflag:

			self.ufinish=self.ures+1

		else:
			
			self.ufinish=self.ures

		if self.vflag:

			self.vfinish=self.vres+1

		else:

			self.vfinish=self.vres

		self.ustep=(self.a360/self.ures)*self.upart
		self.vstep=(self.a360/self.vres)*self.vpart

		if self.xscale!=1.0:
			
			self.xscaleflag=1
			
		else:
			
			self.xscaleflag=0		

		if self.yscale!=1.0:
			
			self.yscaleflag=1
			
		else:
			
			self.yscaleflag=0			
				
		self.rowlist=[]



	def generatepoints(self):



		for i in range(self.ufinish):

			row=[]

			for j in range(self.vfinish):

				u=self.ustep*i+self.uphase
				v=self.vstep*j+self.vphase


			#	if self.xscaleflag:

			#		u=self.ellipsecomp(self.xscale,u) 

			#	if self.yscaleflag:
					
			#		v=self.ellipsecomp(self.yscale,v)


				if self.sform[12]:
					
					r1=self.superform(self.sform[0],self.sform[1],self.sform[2],self.sform[3],self.sform[14]+u,self.sform[4],self.sform[5],self.sform[16]*v)

				else:
				
					r1=1.0
					
				if self.sform[13]:
				
					r2=self.superform(self.sform[6],self.sform[7],self.sform[8],self.sform[9],self.sform[15]+v,self.sform[10],self.sform[11],self.sform[17]*v)
				
				else:
				
					r2=1.0

				x,y,z=self.formula(u,v,r1,r2)

				point=vertex(x,y,z)

				row.append(point)
				self.verts.append(point)
				
			self.rowlist.append(row)
			
		if self.vflag:

			pass

		else:

			for i in range(len(self.rowlist)):
				
				self.rowlist[i].append(self.rowlist[i][0])

		if  self.uflag:

			pass

		else:

			self.rowlist.append(self.rowlist[0])

	def formula(self,u,v,r1,r2):

		pass

	def generatefaces(self):

		ufin=len(self.rowlist)-1
		vfin=len(self.rowlist[0])-1

		for i in range(ufin):

			for j in range(vfin):

				top=i
				bottom=i+1
				left=j
				right=j+1


				a=self.rowlist[top][left]
				b=self.rowlist[top][right]
				c=self.rowlist[bottom][right]
				d=self.rowlist[bottom][left]

				face1=face([a,b,c,d])

				self.faces.append(face1)

				edge1=edge(a,b)
				edge2=edge(a,d)

				self.edges.append(edge1)
				self.edges.append(edge2)

				if i+1==ufin:

					edge3=edge(d,c)
					self.edges.append(edge3)


				if j+1==vfin:

					edge4=edge(b,c)
					self.edges.append(edge4)
	

class grid(form):

	def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):

		form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)

		unit=1.0/self.a360
		
		self.ustep=self.a360/(self.ures-1)
		self.vstep=self.a360/(self.vres-1)
		
		self.uflag=1
		self.vflag=1
			
		self.xscaleflag=0		
		self.yscaleflag=0

		self.uexpand=unit*self.uscale
		self.vexpand=unit*self.vscale

		self.ushift=self.uscale*0.5
		self.vshift=self.vscale*0.5
		
		self.generatepoints()
		self.generatefaces()

		for i in range(len(self.verts)):

			self.verts[i].index=i

		self.connectivity()
				
	def formula(self,u,v,r1,r2):
	
		x=u*self.uexpand-self.ushift
		y=v*self.vexpand-self.vshift
		z=r1*r2-1.0
		
		return x,y,z



class cylinder(form):

	def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):

		form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)

		unit=1.0/self.a360
		self.vshift=self.vscale*0.5
		self.vexpand=unit*self.vscale
		self.vflag=1	
		self.generatepoints()
		self.generatefaces()

		for i in range(len(self.verts)):

			self.verts[i].index=i

		
		self.connectivity()	

	def formula(self,u,v,r1,r2):
	
		x=sin(u)*self.uscale*r1*r2*self.xscale
		y=cos(u)*self.uscale*r1*r2
		z=v*self.vexpand-self.vshift
		
		return x,y,z



class parabola(form):

	def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):

		form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)

		unit=1.0/self.a360
		self.vshift=self.vscale*0.5
		self.vexpand=unit*self.vscale
		self.vflag=1
		self.generatepoints()
		self.generatefaces()

		for i in range(len(self.verts)):

			self.verts[i].index=i

		self.connectivity()		
	
	def formula(self,u,v,r1,r2):
		
		factor=sqrt(v)+0.001
	
		x=sin(u)*factor*self.uscale*r1*r2*self.xscale
		y=cos(u)*factor*self.uscale*r1*r2
		z=-v*self.vexpand+self.vshift
		
		return x,y,z

		
class torus(form):
	
	def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):

		form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)

		self.generatepoints()
		self.generatefaces()

		for i in range(len(self.verts)):

			self.verts[i].index=i

		self.connectivity()		
		
					
	def formula(self,u,v,r1,r2):
	
		z=sin(v)*self.uscale*r2*self.yscale
		y=(self.vscale+self.uscale*cos(v))*cos(u)*r1*r2
		x=(self.vscale+self.uscale*cos(v))*sin(u)*r1*r2*self.xscale

		return x,y,z


class sphere(form):
	
	def __init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform):

		form.__init__(self,uresolution,vresolution,uscale,vscale,upart,vpart,uphase,vphase,utwist,vtwist,xscale,yscale,sform)

		self.vstep=(self.a360/(self.vres-1))*self.vpart
		self.vflag=1
		self.generatepoints()
		self.generatefaces()

		for i in range(len(self.verts)):

			self.verts[i].index=i

		self.connectivity()		
		
					
	def formula(self,u,v,r1,r2):
		
		v=(v*0.5)-(self.a360*0.25)
	
		x=r1*cos(u)*r2*cos(v)*self.uscale*self.xscale
		y=r1*sin(u)*r2*cos(v)*self.uscale
		z=r2*sin(v)*self.uscale*self.yscale

		return x,y,z

