## vert class and overloading experiments
import math
from math import sqrt,acos,pi,sin,cos,atan,tan,fabs
from Blender import NMesh

class vertex:

	def __init__(self,x=0,y=0,z=0):

		self.x=x
		self.y=y
		self.z=z
		self.length=0
		self.index=0
		self.normal=0
		self.edges=[]
		self.faces=[]
		self.boundary=0

	def findlength(self):

		self.length=sqrt(self.x*self.x+self.y*self.y+self.z*self.z)

	def normalize(self):

		self.findlength()

		self.x=self.x*(1.0/self.length)
		self.y=self.y*(1.0/self.length)
		self.z=self.z*(1.0/self.length)
		self.length=1.0

	def findnormal(self):

		target=[]
		for currentface in self.faces:

			target.append(currentface.normal)

		self.normal=average(target).centroid()

		self.normal.findlength()
		self.normal.normalize()

	def clockwise(self):

		if self.boundary:

			start=self.boundarystart()

		else:

			start=self.faces[0]

		self.tempedges=[]
		self.tempfaces=[]

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

			self.tempfaces.append(start)

			for corner in start.corners:

				if corner[0] is not self:

					pass

				elif corner[0] is self:

					self.tempedges.append(corner[1])
					nextedge=corner[2]


			for facey in nextedge.faces:

				if facey is not start:

					start=facey
					break


		self.edges=self.tempedges
		self.faces=self.tempfaces



	def boundarystart(self):

		pass

	def __add__(self,other):

		x=self.x+other.x
		y=self.y+other.y
		z=self.z+other.z

		return vertex(x,y,z)

	def __sub__(self,other):

		x=self.x-other.x
		y=self.y-other.y
		z=self.z-other.z

		return vertex(x,y,z)


	def __mul__(self,other):

		x=self.x*other
		y=self.y*other
		z=self.z*other

		return vertex(x,y,z)

	def __div__(self,other):

		x=self.x*(1/other)
		y=self.y*(1/other)
		z=self.z*(1/other)

		return vertex(x,y,z)

	def negative(self):

		return vertex(-self.x,-self.y,-self.z)

class crossp:

	##   Takes in two vertices(vectors), returns the cross product.
	def __init__(self,v1,v2):

		self.v1=v1
		self.v2=v2
	#	self.docrossproduct(v1,v2)
#
	def docrossproduct(self):

		x=(self.v1.y*self.v2.z)-(self.v2.y*self.v1.z)
		y=(self.v1.z*self.v2.x)-(self.v2.z*self.v1.x)
		z=(self.v1.x*self.v2.y)-(self.v2.x*self.v1.y)

		return vertex(x,y,z)

class average:

	##   Takes a list of vertices and returns the average. If two verts are passed, returns midpoint.

	def __init__(self,vertlist):

		self.vertlist=vertlist
	#	self.centroid()


	def centroid(self):

		x=y=z=0
		divisor=len(self.vertlist)
		for vert in self.vertlist:

			x=x+vert.x
			y=y+vert.y
			z=z+vert.z

		return vertex(x/divisor,y/divisor,z/divisor)

class edge:

	def __init__(self,a=0,b=0):

		self.a=a
		self.b=b

		self.index=0
		self.normal=0
		self.cross=0
		self.unit=0
		self.faces=[]
		self.vect=0
		self.vectb=0
#		self.length=0
		self.boundary=0

		self.findvect()
#		print "vect len before",self.vect.length
		self.findlength()
#		print "vect after",self.vect.length
	def findvect(self):

		self.vect=self.b-self.a
		self.vectb=self.a-self.b

	def findlength(self):
		#print "in edge findlength"
		self.vect.findlength()
		self.vectb.length=self.vect.length

	def findnormal(self):
				
		if self.boundary:

			self.normal=self.faces[0].normal	#average([self.a,self.b]).centroid()	
			
		else:
	
			self.normal=average([self.faces[0].normal,self.faces[1].normal]).centroid()
		
		self.normal.normalize()

# 	def findother(self,vertindex):
#
# 		if vertindex==self.a:
#
# 			return self.b
#
# 		else:
# 			return self.a

##		different classes for 3,4,> sides??

class face:

	def __init__(self,vertices=[]):

		self.vertices=vertices	##   List of vertex instances.
		self.edges=[]			##   Will be filled with the sides of the face.
		self.boundary=0		##   When set will have bool and id of edge concerned.
		self.normal=0			##   Face normal found through cross product.
		self.corners=[]
		self.spokes=[]			##   Vectors of the bisecting angles from each corner to the centre + dotproduct.
		self.index=0

	def dotproduct(self,v1,v2):
	#	print "dp ",v1.x,v1.y,v1.z,"   ",v2.x,v2.y,v2.z
	#	print "v1 length",v1.length
	#	print "v2 length",v2.length
		
		v1.findlength()
		v2.findlength()
		
	#	print "v1 length",v1.length
	#	print "v2 length",v2.length
		dot=(v1.x*v2.x)+(v1.y*v2.y)+(v1.z*v2.z)
		costheta=dot/(v1.length*v2.length)

		return acos(costheta)

	def orderedges(self):

		temp=[]
		finish=len(self.vertices)
		for i in range(finish):

			current=self.vertices[i]
			if i==finish-1:
				next=self.vertices[0]
			else:
				next=self.vertices[i+1]

			for edge in face.edges:
				if edge.a==current and edge.b==next:

					face.clockw.append(edge.vect)
					face.aclockw.append(edge.vectb)
					temp.append(edge)

				if edge.b==current and edge.a==next:

					face.clockw.append(edge.vectb)
					face.aclockw.append(edge.vect)
					temp.append(edge)

			face.vertices=temp


	def docorners(self):
		##   This function identifies and stores the vectors coming from each vertex
		##   allowing easier calculation of cross and dot products.

		finish=len(self.vertices)
		for i in range(finish):

			current=self.vertices[i]

			if i==finish-1:

				next=self.vertices[0]

			else:

				next=self.vertices[i+1]

			if i==0:

				previous=self.vertices[-1]

			else:

				previous=self.vertices[i-1]

			corner=[current]

			for edge in self.edges:

				if edge.a is current or edge.b is current:	##  does this edge contain our current vert

					if edge.a is current:

						if edge.b is next:

							rightedge=edge
							rightvect=edge.vect

						if edge.b is previous:

							leftedge=edge
							leftvect=edge.vect

					elif edge.b is current:

						if edge.a is next:

							rightedge=edge
							rightvect=edge.vectb
						if edge.a is previous:

							leftedge=edge
							leftvect=edge.vectb
							
			corner.append(rightedge)
			corner.append(leftedge)
	#		print "corner stuff  vert",current.index,"rightedge",rightedge.index,"leftedge",leftedge.index
	#		print "corner",corner
			dotty=self.dotproduct(rightvect,leftvect)
			corner.append(dotty)
	#		print "corner",corner
			self.corners.append(corner)

	def findnormal(self):

		one=self.corners[1][2]
		two=self.corners[1][1]

		if one.a is self.corners[1][0]:
			one=one.vect

		elif one.b is self.corners[1][0]:
			one=one.vectb

		if two.a is self.corners[1][0]:
			two=two.vect

		elif two.b is self.corners[1][0]:
			two=two.vectb
	#	print "crossp 1",one,"crossp 2",two
		self.normal=crossp(one,two).docrossproduct()
		self.normal.findlength()
		self.normal.normalize()

	def dospokes(self):

		for corner in self.corners:

			vert=corner[0]
			right=corner[1]
			left=corner[2]

			if right.a is vert:

				one=vertex(right.vect.x,right.vect.y,right.vect.z)

			elif right.b is vert:

				one=vertex(right.vectb.x,right.vectb.y,right.vectb.z)

			if left.a is vert:

				two=vertex(left.vect.x,left.vect.y,left.vect.z)

			elif left.b is vert:

				two=vertex(left.vectb.x,left.vectb.y,left.vectb.z)
			
			one.normalize()
			two.normalize()

			spoke=one+two
			spoke.normalize()
			self.spokes.append(spoke)

	def artspokes(self):

		centre=average(self.vertices).centroid()

		for point in self.vertices:

			newedge=edge(point,centre)
			spokes.append(newedge)

			
class mesh:

	def __init__(self):

		self.verts=[]
		self.edges=[]
		self.faces=[]

		self.edgeflag=0
		self.faceflag=0
		self.vertexflag=0

		self.vertedgeflag=0
		self.vertfaceflag=0
		self.faceedgeflag=0

		self.boundaryflag=0

		self.vertnormalflag=0
		self.edgenormalflag=0
		self.facenormalflag=0

	def power(self,a,b):         ## Returns a power, including negative numbers

		result=self.sign(a)*(abs(a)**b)

		return result

	def sign(self,d):    ## Works out the sign of a number.

		if d<0:

			return -1

		elif d>0:

			return 1

		elif d==0:

			return 0


	def ellipsecomp(self,efactor,theta):

		if theta==self.a90:

			result=self.a90

		elif theta==self.a180:

			result=self.a180

		elif theta==self.a270:

			result=self.a270

		elif theta==self.a360:

			result=0.0

		else:
                        
			result=atan(tan(theta)/efactor**0.5)

			if result<0.0:

				if theta>self.a180:

					result=result+self.a180

				elif theta<self.a180:

					result=result+self.a180
	##  Fishy - check this.
			if result>0.0:

				if theta>self.a180:

					result=result+self.a180

				elif theta<self.a180:

					result=result



		return result
		
	def connectivity(self):

		self.dovertedge()
		self.dovertface()
		self.dofaceedge()
		self.boundary()

	def superell(self,n1,uv,turn):

		t1=sin(uv+turn)
		t1=abs(t1)
		t1=t1**n1

		t2=cos(uv+turn)
		t2=abs(t2)
		t2=t2**n1

		r=self.power(1.0/(t1+t2),(1.0/n1))

		return r

	def superform(self,m,n1,n2,n3,uv,a,b,twist):

		t1=cos(m*(uv+twist)/4)/a
		t1=abs(t1)
		t1=t1**n2

		t2=sin(m*(uv+twist)/4)/b
		t2=abs(t2)
		t2=t2**n3

		r=self.power(1.0/(t1+t2),(1.0/n1))
		
		if abs(r)==0:
			x=0
			y=0


		return r


	def dovertedge(self):

		if not self.vertedgeflag:

			for vert in self.verts:
				vert.edges=[]

			for currentedge in self.edges:

				currentedge.a.edges.append(currentedge)
				currentedge.b.edges.append(currentedge)

		self.vertedgeflag=1

	def dovertface(self):

		if not self.vertfaceflag:

			for vert in self.verts:
				vert.faces=[]

			for face in self.faces:

				for vert in face.vertices:

					vert.faces.append(face)

		self.vertfaceflag=1

	def dofaceedge(self):

		self.dovertedge()	## just in case they haven't been done
		self.dovertface()	##


		if not self.faceedgeflag:

			for edge in self.edges:

				edge.faces=[]

			for face in self.faces:

				face.edges=[]


			for face in self.faces:

				finish=len(face.vertices)

				for i in range(finish):

					current=face.vertices[i]

					if i==finish-1:


						next=face.vertices[0]

					else:

						next=face.vertices[i+1]

					for edge in current.edges:

						if edge.a is current or edge.b is current:

							if edge.b is next or edge.a is next:

								edge.faces.append(face)
								face.edges.append(edge)

		self.faceedgeflag=1


	def boundary(self):

		if not self.boundaryflag:

			for edge in self.edges:

				if len(edge.faces)<2:

					edge.boundary=1
					edge.faces[0].boundary=1
					edge.a.boundary=1
					edge.b.boundary=1


					
##   The functions below turn the basic triangular faces into
##   hexagonal faces, creating the buckyball effect.
	def hexify(self):

		self.hexverts=[]
		self.hexedges=[]
		self.hexfaces=[]

		for i in range(len(self.verts)):
			self.verts[i].index=i

		for i in range(len(self.edges)):
			self.edges[i].index=i

		self.connectivity()

		for edge in self.edges:

			self.hexshorten(edge)

		for face in self.faces:

			self.makehexfaces(face)

		for vert in self.verts:

			vert.clockwise()

			self.hexvertface(vert)

		self.verts=self.hexverts
		self.edges=self.hexedges
		self.faces=self.hexfaces

		self.vertedgeflag=0
		self.vertfaceflag=0
		self.faceedgeflag=0

	def hexshorten(self,currentedge):

		third=currentedge.vect/3.0

		newvert1=vertex(currentedge.a.x,currentedge.a.y,currentedge.a.z)
		newvert2=vertex(currentedge.b.x,currentedge.b.y,currentedge.b.z)

		newvert1=newvert1+third
		newvert2=newvert2-third

		newedge=edge(newvert1,newvert2)

		newedge.index=currentedge.index

		self.hexverts.append(newvert1)
		self.hexverts.append(newvert2)

		self.hexedges.append(newedge)

	def makehexfaces(self,currentface):

		vertices=[]
		
		currentface.docorners()
		
		for corner in currentface.corners:

			vert=corner[0]
			rightedge=corner[1]
			leftedge=corner[2]
			lid=leftedge.index
			rid=rightedge.index

			if leftedge.a is vert:

				vertices.append(self.hexedges[lid].a)

			elif leftedge.b is vert:

				vertices.append(self.hexedges[lid].b)

			if rightedge.a is vert:

				vertices.append(self.hexedges[rid].a)

			elif rightedge.b is vert:

				vertices.append(self.hexedges[rid].b)

		newface=face(vertices)
#		print "len hexface vertices",len(vertices)

		newedge1=edge(vertices[0],vertices[1])
		newedge2=edge(vertices[2],vertices[3])
		newedge3=edge(vertices[4],vertices[5])

		self.hexfaces.append(newface)

		self.hexedges.append(newedge1)
		self.hexedges.append(newedge2)
		self.hexedges.append(newedge3)

	def hexvertface(self,vert):

		vertices=[]

		for edge in vert.edges:

			eid=edge.index

			if edge.a is vert:

				vertices.append(self.hexedges[eid].a)


			elif edge.b is vert:

				vertices.append(self.hexedges[eid].b)

		newface=face(vertices)

		self.hexfaces.append(newface)


	def starify(self):

		self.starverts=[]
		self.staredges=[]
		self.starfaces=[]

		for i in range(len(self.verts)):
			self.verts[i].index=i

		for i in range(len(self.edges)):
			self.edges[i].index=i

		self.connectivity()

		for currentedge in self.edges:

			newvert=average([currentedge.a,currentedge.b]).centroid()
			self.starverts.append(newvert)

		for currentface in self.faces:

			currentface.docorners()

			vertices=[]

			for corner in currentface.corners:

				vert=self.starverts[corner[1].index]
				vertices.append(vert)

			newface=face(vertices)

			newedge1=edge(vertices[0],vertices[1])
			newedge2=edge(vertices[1],vertices[2])
			newedge3=edge(vertices[2],vertices[0])

			self.starfaces.append(newface)

			self.staredges.append(newedge1)
			self.staredges.append(newedge2)
			self.staredges.append(newedge3)


		for vert in self.verts:

			vertices=[]
			vert.clockwise()
			for currentedge in vert.edges:

				eid=currentedge.index

				vertices.append(self.starverts[eid])

			newface=face(vertices)

			self.starfaces.append(newface)

		self.verts=self.starverts
		self.edges=self.staredges
		self.faces=self.starfaces

		self.vertedgeflag=0
		self.vertfaceflag=0
		self.faceedgeflag=0

	def class2(self):
		
		self.class2verts=[]
		self.class2edges=[]
		self.class2faces=[]
		
		newvertstart=len(self.verts)
		newedgestart=len(self.edges)

		for i in range(len(self.verts)):
			self.verts[i].index=i

		for i in range(len(self.edges)):
			self.edges[i].index=i

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

			self.faces[i].index=i
			
		self.connectivity()
			
		for currentface in self.faces:
			currentface.docorners()
			newvert=average(currentface.vertices).centroid()
			self.verts.append(newvert)

		#	print "len verts",len(self.verts)
			
			newedge1=edge(currentface.vertices[0],newvert)
			newedge2=edge(currentface.vertices[1],newvert)
			newedge3=edge(currentface.vertices[2],newvert)
			
			self.edges.append(newedge1)
			self.edges.append(newedge2)
			self.edges.append(newedge3)
			
		for currentedge in range(newedgestart):
			
		#	print "v index",self.verts[self.edges[currentedge].faces[0].index+newvertstart]
		#	print "v index",self.verts[self.edges[currentedge].faces[1].index+newvertstart]

			self.edges[currentedge].a=self.verts[self.edges[currentedge].faces[0].index+newvertstart]
			self.edges[currentedge].b=self.verts[self.edges[currentedge].faces[1].index+newvertstart]
			self.edges[currentedge].findvect()
				
		for currentvert in range(newvertstart):
			
			vert=self.verts[currentvert]
			vertices=[]
			vert.clockwise()
			for currentface in vert.faces:

				eid=currentface.index

				vertices.append(self.verts[newvertstart+eid])
				
			for i in range(len(vertices)):
			
				if i==len(vertices)-1:
				
					next=vertices[0]
					
				else:
				
					next=vertices[i+1]
				
				newface=face([vert,vertices[i],next])

				self.class2faces.append(newface)
			
		#self.verts=self.class2verts
		#self.edges=self.class2edges
		self.faces=self.class2faces

		self.vertedgeflag=0
		self.vertfaceflag=0
		self.faceedgeflag=0	
		
		
	def dual(self):

		self.dualverts=[]
#		self.dualedges=[]
		self.dualfaces=[]

		for i in range(len(self.verts)):
			self.verts[i].index=i

		for i in range(len(self.edges)):
			self.edges[i].index=i

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

			self.faces[i].index=i

		self.connectivity()

		for currentface in self.faces:
			currentface.docorners()
			newvert=average(currentface.vertices).centroid()
			self.dualverts.append(newvert)

		for vert in self.verts:

			vertices=[]
			vert.clockwise()
			for currentface in vert.faces:

				eid=currentface.index

				vertices.append(self.dualverts[eid])

			newface=face(vertices)

			self.dualfaces.append(newface)

		for currentedge in self.edges:

			currentedge.a=self.dualverts[currentedge.faces[0].index]
			currentedge.b=self.dualverts[currentedge.faces[1].index]

		self.verts=self.dualverts
#		self.edges=self.staredges
		self.faces=self.dualfaces

		self.vertedgeflag=0
		self.vertfaceflag=0
		self.faceedgeflag=0

 


class facetype(mesh):

	def __init__(self,basegeodesic,parameters,width,height,relative):

		mesh.__init__(self)
		
		self.detatch=parameters[0]
		self.endtype=parameters[1]
		self.coords=parameters[2]
		self.base=basegeodesic
		self.relative=relative
		self.width=width
	
		if not self.relative:

			newwidth=self.findrelative()
			self.width=width*newwidth


		self.height=height

		self.base.connectivity()

		for coord in self.coords:

			coord[0]=coord[0]*self.width
			coord[1]=coord[1]*self.height

		if not self.base.facenormalflag:

			for currentface in self.base.faces:

			#	print "face normal ",currentface.normal
				currentface.docorners()
				currentface.findnormal()

			#	print "face normal ",currentface.normal.x,currentface.normal.y,currentface.normal.z

			self.base.facenormalflag=1

		if self.endtype==4 and not self.base.vertnormalflag:

			for currentvert in self.base.verts:

				currentvert.findnormal()
			
			self.base.vertnormalflag=1

		self.createfaces()

	def findrelative(self):

		centre=average(self.base.faces[0].vertices).centroid()
		edgelist=[]
		for point in self.base.faces[0].vertices:

			newedge=edge(centre,point)
			edgelist.append(newedge)
		length=0
		for edg in edgelist:
			extra=edg.vect.length
			length=length+extra
		#	print "length",length,"extra",extra

		length=length/len(edgelist)
	#	print "find relative",length
		return length

	def createfaces(self):

		if not self.detatch:

			for point in self.base.verts:

				self.verts.append(point)

		if self.endtype==4:

			self.createghostverts()

		for currentface in self.base.faces:

			self.doface(currentface)

	def createghostverts(self):

		self.ghoststart=len(self.verts)

		for vert in self.base.verts:

		#	print "vert.normal",vert.normal," self.coords[-1][1] ",self.coords[-1][1]
			newvert=vert+(vert.normal*self.coords[-1][1])

			self.verts.append(newvert)
		
	def doface(self,candidate):

		grid=[]

		candidate.dospokes()
	#	print "Candidate normal",candidate.normal.x,candidate.normal.y,candidate.normal.z
		if not self.detatch:

			line=[]
			for vert in candidate.vertices:

				line.append(vert)

			grid.append(line)

		else:

			line=[]
			for point in candidate.vertices:

				newvert=vertex(point.x,point.y,point.z)
				self.verts.append(newvert)
				line.append(newvert)

			grid.append(line)

		finish=len(self.coords)

		if self.endtype==1 or self.endtype==4:

			finish=finish-1

		for i in range(finish):

			up=candidate.normal*self.coords[i][1]
			line=[]

			for j in range(len(candidate.vertices)):
						
				dotfac=candidate.corners[j][3]*0.5
				vec=(candidate.spokes[j]*(self.coords[i][0]/sin(dotfac)))		#self.coords[i][0])#(self.coords[i][0]/sin(dotfac)))#+up

				newvert=candidate.vertices[j]+vec+up

				line.append(newvert)
				self.verts.append(newvert)

			grid.append(line)

		if self.endtype==4:
					
			line=[]

			for i in range(len(candidate.vertices)):
				
				vert=self.verts[candidate.vertices[i].index+self.ghoststart]
				line.append(vert)
			#	self.verts.append(vert)
				
			grid.append(line)

		for line in grid:

			line.append(line[0])

		if self.endtype==3:

			grid.append(grid[0])

		for i in range(len(grid)-1):

			for j in range(len(grid[i])-1):

				one=grid[i][j]
				two=grid[i][j+1]
				three=grid[i+1][j+1]
				four=grid[i+1][j]

				newface=face([one, two, three, four])
				self.faces.append(newface)

		if self.endtype==2:
			finalfaceverts=grid[-1]

			newface=face(finalfaceverts[:-1])
			self.faces.append(newface)

		if self.endtype==1:

			lastvert=average(candidate.vertices).centroid()
			up=candidate.normal*self.coords[-1][1]
			newvert=lastvert+up

			self.verts.append(newvert)

			ring=grid[-1]

			for i in range(len(ring)-1):

				newface=face([newvert,ring[i],ring[i+1]])
				self.faces.append(newface)

class importmesh(mesh):
		
	def __init__(self,meshname,breakquadflag):	

		mesh.__init__(self)
		
		print "mesh and breakquad",meshname,breakquadflag
		
		impmesh=NMesh.GetRawFromObject(meshname)

		for v in impmesh.verts:

			x=v.co[0]
			y=v.co[1]
			z=v.co[2]
			
			vert=vertex(x,y,z)
			self.verts.append(vert)

		indexcount=0
		
		for f in impmesh.faces:
			
			temp=[]
			
			for vert in f.v:

				a=self.verts[vert.index]
				temp.append(a)
				
			newface=face(temp)
			newface.index=indexcount
			indexcount+=1
	
			self.faces.append(newface)
		
		self.dovertedge()
		self.dovertface()
	
		self.temp=[]	
			
		for i in range(len(self.verts)):
			
			self.temp.append([])
					
			self.verts[i].index=i
			
		if breakquadflag:			
			for facey in self.faces:

				if len(facey.vertices)>3:
					#print "quad"
					self.breakquad(facey)
		
		for i in range(len(self.verts)):

			target=self.surroundingverts(self.verts[i])	

			for j in range(len(target)):				## go through those verts

				temptarg=self.temp[target[j].index]		

				flag=0					## set a flag up
		
				for k in range(len(temptarg)):		## go through temp list for each of those verts
					
					if temptarg[k]==i:			## if we find a match to the current vert...

						flag=1			## raise the flag
			
				if flag==0:				## if there is no flag after all that...

					self.temp[target[j].index].append(i)	## add current vert to temp list of this surrounding vert
					self.temp[i].append(target[j].index)	## add this surrounding vert to the current temp list
					newedge=edge(self.verts[i],self.verts[target[j].index])
					self.edges.append(newedge)	## add the newly found edge to the edges list

		
		for edg in self.edges:

			edg.findvect()


		self.vertedgeflag=0	
		self.vertedgeflag=0	
		self.connectivity()
													


	def surroundingverts(self,vert):

		''' Find the verts surrounding vert'''
		
		surround=[]					## list to be filled and returned
		
		for faces in vert.faces:		## loop through faces attached to vert

			finish=len(faces.vertices)
			for i in range(finish):
			
				if i==finish-1:

					next=faces.vertices[0]

				else:
					next=faces.vertices[i+1]

				if vert==faces.vertices[i]:

					surround.append(next)				
					
		return surround




	def breakquad(self,quad):

		''' turn quads into triangles'''

		distance1=quad.vertices[0]-quad.vertices[2]
		distance2=quad.vertices[1]-quad.vertices[3]
		
		distance1.findlength()
		distance2.findlength()
		
		if abs(distance1.length)<abs(distance2.length):

			self.faces[quad.index]=face([quad.vertices[0],quad.vertices[1],quad.vertices[2]])
			self.faces.append(face([quad.vertices[0],quad.vertices[2],quad.vertices[3]]))

		else:

			self.faces[quad.index]=face([quad.vertices[0],quad.vertices[1],quad.vertices[3]])
			self.faces.append(face([quad.vertices[1],quad.vertices[2],quad.vertices[3]]))			
		
						
class strut(mesh):

	def __init__(self,base,struttype,width,height,length,widthtog,heighttog,lengthtog,meshname,stretchflag,lift):

		mesh.__init__(self)
		
		## put in strut prep stuff here
		if struttype==None:
			return
				
		total=0
		divvy=len(base.faces[0].edges)

		for lengf in base.faces[0].edges:
			
			lengf.vect.findlength()
			total=total+lengf.vect.length
			
		yardstick=total/divvy
				
		if widthtog:

			self.width=width

		else:
			self.width=width*yardstick

		if heighttog:

			self.height=height

		else:
			self.height=height*yardstick

		if lengthtog:

			self.shrink=length

		else:
			self.shrink=length#*yardstick		
			
		if not base.facenormalflag:

			for currentface in base.faces:

				currentface.docorners()
				currentface.findnormal()

			base.facenormalflag=1
					
		for edj in base.edges:

			edj.findnormal()
			side=edge(edj.a,edj.b)
			edj.unit=side.vect
			edj.unit.normalize()	
			edj.cross=crossp(edj.normal,edj.unit).docrossproduct()
		
		print "meshname",meshname	
		template=importmesh(meshname,0)
		
		maxx=0
		minx=0
		
		for vert in template.verts:

			if vert.x>maxx:

				maxx=vert.x

			if vert.x<minx:

				minx=vert.x

		for edj in base.edges:

			start=len(self.verts)

			centre=average([edj.a,edj.b]).centroid()
	
	
			split=edj.vect.length/2
			dubbl=edj.vect.length/(maxx-minx)
			
			diffplus=split-maxx
			diffminus=-split-minx
		
			for point in template.verts:
				
				ay=(edj.normal*point.z*self.height)+(edj.normal*lift)
				ce=edj.cross*point.y*self.width
				
	
				if stretchflag:
									
					be=edj.unit*self.shrink*dubbl*point.x
													
				else:
																									
					if point.x>0.0:	
											
						be=edj.unit*self.shrink*(point.x+diffplus)
						
					elif point.x<0.0:	
						
	
						be=edj.unit*self.shrink*(point.x+diffminus)
			
					elif point.x==0.0:
					
						be=edj.unit*self.shrink*point.x
				
				de=ay+be+ce
			
				newvert=centre+de
			
				self.verts.append(newvert)

			for edjy in template.edges:
			
				one=edjy.a.index+start
				two=edjy.b.index+start
				
				newedge=edge(self.verts[one],self.verts[two])
				self.edges.append(newedge)
			
			for facey in template.faces:

				faceverts=[]

				for verty in facey.vertices:
					
					index=verty.index+start
					faceverts.append(self.verts[index])
				newface=face(faceverts)
				self.faces.append(newface)

		self.vertedgeflag=0	
		self.vertedgeflag=0						
		self.connectivity()	
			
		
		
		
class hub(mesh):

	def __init__(self,base,hubtype,width,height,length,widthtog,heighttog,lengthtog,meshname):

		mesh.__init__(self)
		
		## put in strut prep stuff here
		if hubtype==None:
			return
				
		total=0
		divvy=len(base.faces[0].edges)

		for lengf in base.verts[0].edges:
			
			lengf.vect.findlength()
			total=total+lengf.vect.length
			
		yardstick=total/divvy
				
		if widthtog:

			self.width=width

		else:
			self.width=width*yardstick

		if heighttog:

			self.height=height

		else:
			self.height=height*yardstick

		if lengthtog:

			self.shrink=length

		else:
			self.shrink=length*yardstick		
			
		if not base.facenormalflag:

			for currentface in base.faces:

				currentface.docorners()
				currentface.findnormal()

			base.facenormalflag=1
					
		for apex in base.verts:

			apex.findnormal()
			side=edge(apex.edges[0].a,apex.edges[0].b)
			apex.unit=side.vect
			apex.unit.normalize()	
			apex.cross=crossp(apex.normal,apex.unit).docrossproduct()
			apex.unit=crossp(apex.cross,apex.normal).docrossproduct()
			
		template=importmesh(meshname,0)
	
		
		for apex in base.verts:

			start=len(self.verts)

			centre=apex	
	
			for point in template.verts:
				
				ay=apex.normal*point.z*self.height
				ce=apex.cross*point.y*self.width
				be=apex.unit*point.x*self.shrink
									
				de=ay+be+ce
			
				newvert=centre+de
			
				self.verts.append(newvert)

			for edjy in template.edges:
			
				one=edjy.a.index+start
				two=edjy.b.index+start
				
				newedge=edge(self.verts[one],self.verts[two])
				self.edges.append(newedge)
			
			for facey in template.faces:

				faceverts=[]

				for verty in facey.vertices:
					
					index=verty.index+start
					faceverts.append(self.verts[index])
				newface=face(faceverts)
				self.faces.append(newface)

		self.vertedgeflag=0	
		self.vertedgeflag=0						
		self.connectivity()	


def finalfill(source,target):
	count=0
	for point in source.verts:

		newvert=NMesh.Vert(point.x,point.y,point.z)
		target.verts.append(newvert)
		point.index=count
		count=count+1
	
	for facey in source.faces:

		row=len(facey.vertices)

		if row>=5:

			newvert=average(facey.vertices).centroid()

			centre=NMesh.Vert(newvert.x,newvert.y,newvert.z)
			target.verts.append(centre)

			for i in range(row):

				f=NMesh.Face()

				if i==row-1:

					a=target.verts[facey.vertices[-1].index]
					b=target.verts[facey.vertices[0].index]


				else:

					a=target.verts[facey.vertices[i].index]
					b=target.verts[facey.vertices[i+1].index]

				c=centre

				f.v.append(a)
				f.v.append(b)
				f.v.append(c)

				target.faces.append(f)

		else:

			f=NMesh.Face()

			for j in range(len(facey.vertices)):

				a=facey.vertices[j]

				f.v.append(target.verts[a.index])

			target.faces.append(f)
			