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)