split up mesh performance prob

Hi, I have been writing on my first script. it splits up the mesh into fragments of different size which still form a closed surface. it should work
with with any surface.
my problem is that as soon as the total number of
faces is more than 500 the script slows down a lot. so I would appreciate any help or advice on how to get a better performance for meshes with a
high number of faces (up to about 5000). maybe there is some way of writing the code in recursive form…I don’t know. I appended the code feel free to enjoy it.

to get an impression of what the script does, just create a cube, subdivide it two or three times (don’t make it to often, cos it will slow down the performnce incredibly down…I warned you), then start the script with Alt-P (the cube must be selected in obj-mode) have fun. the material-settings are just for visualisation.

I would also appreciate any comments on the script, as this is my first time experience with programming…

manne



# fragment_mesh(mesh)
# make clusters of n-fragments out of a mesh

# functionlist:
# get_obj_name()
# split_mesh(obj_name,sorted_list,f)
# draw_fragments(mesh_list)

# quadszerlegung

import Blender
from Blender import *
from Blender import Material
		
print ("--- start ---")

#-------------------------------------------
# get the selected obj.name
# ------------------------------------------

def get_obj_name():
	sce = Blender.Scene.GetCurrent()
	OL=Blender.Object.GetSelected()
	if len(OL)!=0:
		select=OL[0].name				# picks the first of the selected obj
		return select
	else:
		print ("--- no object selected ---")
		return FALSE

#----------------------------------------------------------
# compare two faces
# ---------------------------------------------------------

def common_edge(f1,f2):
	z=0
	for v1 in f1.v:	
		for v2 in f2.v:
			if v1 == v2:
				z=z+1	
	if z > 1:
		return TRUE
	else:
		return FALSE

# --------------------------
# check for a common vertice			
# --------------------------			
def common_vertice(f1,f2):
	z=0
	for v1 in f1.v:
		for v2 in f2.v:
			if v1 == v2:
				z=z+1
		if z > 0:
			break
			return TRUE
		else:
			return FALSE

# -----------------------
# -----------------------	

def remove_doubles(L1,L2):
	mem=[[]]
	for l1 in L1:
		i=0
		for l2 in L2:
			if l2==[]:
				mem.append(l2)
#				if (l2 == l1) and (L1 == L2):
#				x1=L2.count(l2)
#				x2=mem.count(l2)
#				#print abs(x1-x2)
#				if abs(x1-x2) > 1:
#					mem.append(l2)
			if (l1!=l2):
				for f1 in l1:
					for f2 in l2:
						if (f1==f2):
							#print '-------------- gefunden------------'
							#if l2 in L2:
								mem.append(l2)
		i=i+1
		for r in mem:
			if r in L2:
				L2.remove(r)
	return L2

# -----------------------
# create tuple variations					
# -----------------------

def get_tuples(L1,L2):
	n=len(L2)
	for f in L1:
		for j in range(1,len(f)):
			L2.append([])
			L2[n].extend(f)
			L2[n].remove(f[j])
			if L2.count(L2[n])>1:
				L2.remove(L2[n])
			n=len(L2)
	return L2								
									
# -------------------------------------------------------
# check for neighbours and get a closed mesh of fragments
# -------------------------------------------------------

def zerlege_flaeche(LF):
	q=[] 
	t=[] 
	p=[]
	s=[]
	ones=[]	
	zlist=[]
	min_face=4

	if len(LF)>min_face:
		i=0
		for f1 in LF:
			edges=len(f1.v)
			CF=[]
			n=0
			CF.append(f1)
			q.append([])
			t.append([])
			p.append([])
			s.append([])
			ones.append([])
			for f2 in LF:
				if common_edge(f1,f2) and (f1!=f2):
					CF.append(f2)
					n=n+1
			if (n==4) and (edges==4):
				q[i].extend(CF)
			elif n==3:
				t[i].extend(CF)
			elif n==2:
				p[i].extend(CF)
			elif n==1:
				s[i].extend(CF)
			elif n==0:
				ones[i].extend(CF)
			i=i+1
	t=get_tuples(q,t)
	p=get_tuples(t,p)
	s=get_tuples(p,s)
	ones=get_tuples(s,ones)
	# make sure we have no multiple faces in the lists
	print 'quads: ',len(q)
	print 'remove q,q'
	q=remove_doubles(q,q)
	
	print 'quads: ',len(q)			
	print 'triples: ',len(t)
	print 'remove q,t'
	t=remove_doubles(q,t)

	print 'triples: ',len(t)
	print 'remove t,t'		
	t=remove_doubles(t,t)

	print 'triples: ',len(t)
	print 'pairs: ',len(p)
	print 'remove q,p--t,p--p,p'
	p=remove_doubles(q,p)
	p=remove_doubles(t,p)
	p=remove_doubles(p,p)
	
	print 'pairs: ',len(p)
	print 'singles: ',len(s)
	print 'remove q,s--t,s--p,s--s,s'
	s=remove_doubles(q,s)
	s=remove_doubles(t,s)
	s=remove_doubles(p,s)
	s=remove_doubles(s,s)
	ones=remove_doubles(q,ones)
	ones=remove_doubles(t,ones)
	ones=remove_doubles(p,ones)
	ones=remove_doubles(s,ones)
	
	print '-------------'
	print 'quads: ',len(q)
	print 'triples: ',len(t)
	print 'pairs: ',len(p)
	print 'singles: ',len(s)
	print 'ones: ',len(ones)
	print '-------------'
	total=len(q)+len(t)+len(p)+len(s)+len(ones)
	print 'total fragments: ', total 
	return(q,t,p,s,ones)

#-------------------------------------------
# split up mesh
# ------------------------------------------

def split_mesh(sorted_list,f):
	meshlist=[]
	for i in range(0,len(LF),f):
		newmesh=NMesh.GetRaw()
		for j in range(0,f):
			m=j+i
			if m<len(LF):
				newmesh.faces.append(sorted_list[m])
				for v in sorted_list[m]:
					newmesh.verts.append(v)
			else:
				newmesh.faces.append(sorted_list[i])
				for v in sorted_list[i]:
					newmesh.verts.append(v)
		meshlist.append(newmesh)
	return meshlist
			
	

#-------------------------------------------
# draw the fragments and unlink the original
# ------------------------------------------

def draw_fragments(mesh_list):
	for i in range(0,len(mesh_list)):
		NMesh.PutRaw(mesh_list[i])

# ------------------------------------------
# ------------------------------------------

def showmy_fragments(LF1,matface):
	if len(LF1):
		Obj=[]
		newmesh1=NMesh.GetRaw()
		for f1 in LF1:
			newmesh1.faces.append(f1)
			for v in f1:
				newmesh1.verts.append(v)
		meshobj=NMesh.PutRaw(newmesh1)
		newObj=Blender.Object.Get(meshobj.name)
		ML=[]
		ML.append(matface)
	
		newObj.setMaterials([])
		newObj.setMaterials(ML)
		newObj.colbits=1

		#print meshobj.name
		return TRUE
	else:
		return FALSE
		
			
		
#-------------------------------------------
# start here
# ------------------------------------------		

print get_obj_name()

# -------------------------------------------------
# get the selected object/mesh
# -------------------------------------------------

mesh=Blender.NMesh.GetRawFromObject(get_obj_name())
LF=mesh.faces[:]

# -------------------------------------------------
# create the fragments and sort them in the list
# -------------------------------------------------

liste=zerlege_flaeche(LF)
		
# -----------------------------------------------
# define some materials to identify the fragments
# -----------------------------------------------		
mat=[]
matquad=Blender.Material.New('redface')
matquad.rgbCol = [1,0,0]
mat.append(matquad)
mattriple=Blender.Material.New('blueface')
mattriple.rgbCol = [0,0,1]
mat.append(mattriple)
matpair=Blender.Material.New('greenface')
matpair.rgbCol = [0,1,0]
mat.append(matpair)
matsingle=Blender.Material.New('magface')
matsingle.rgbCol = [1,0,1]
mat.append(matsingle)
matone=Blender.Material.New('yellface')
matone.rgbCol = [1,1,0]
mat.append(matone)
# ------------------------------------------------

# ------------------------------------------------
# draw the fragments of liste
# ------------------------------------------------

j=0
ll=len(liste[j])
for j in range(0,len(liste)):
	for i in range(0,len(liste[j])):
		showmy_fragments(liste[j][i],mat[j])

# ------------------------------------------------
# remove the original object
# ------------------------------------------------
# scene=Blender.Scene.GetCurrent()
# scene.unlink(Blender.Object.Get(get_obj_name()))
# ------------------------------------------------

print 'total number of faces: ', len(LF)