Hi everybody. Yesterday I wrote a script of which I was thinking for quite a few days. Select some unconnected vertices of a mesh then run this script and bingo, they are connected. (Remember this is an alpha version)
See the pics below.
Before
After
Before
After
Before
After
In above pic u can see that this program only makes tris no quads. This will be added later. For more documentation see the code. Now the code.
#!BPY
"""
Name: 'Vertices to Faces v apha1'
Blender: 241
Group: 'Mesh'
Tooltip: 'All selected connected/unconnected vertices are cennected and faces are build.'
"""
__author__ = "Apple Grew"
__email__ = ["Apple Grew, [email protected] (remove the dashes)"]
__version__="alpha1"
__bpydoc__ = """\
Usage: Select the vertices of the mesh which u want to linka and run this script.
Notes:
1)This is aplha version of script.
2) This is designed to work on planes (maybe flat or curved).
3) This works best in places where there is symmetry and there are less obstruction between
the selected vertices.
4) This only makes tris not quads.
5) The script sees ONLY the selected vertices and tries to connect all of them together,
hence if some of the vertices lie someplace far (connected with other vertices) then also
they will be linked together, jumping over all the vertices lying in-between.
"""
# --------------------------------------------------------------------------
# Vertices to Faces
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
from Blender import Object, Draw, Window, NMesh
import math
DEBUG=False
INFINITE=1e308 #on my machine this was the largest no. (approx) which Pyhton could handle.
def error(msg):
Draw.PupMenu("Error%t|"+msg)
def calStdDeviation(X): #where X is a List of elements of whose standard
#deviation is to be found.
if len(X)==0:
return 0
avg=0
for xi in X:
avg=avg+xi
avg=avg/len(X)
sqSum=0
for xi in X:
sqSum=sqSum+ (xi-avg)**2
return math.sqrt(sqSum/len(X))
def calDis(v1,v2): #calculates distance between two vertices.
v1=v1.co #getting coordinate.
v2=v2.co
return math.sqrt((v1.x-v2.x)**2+(v1.y-v2.y)**2)
def rationalizeDis(d): #searches for the largest no. in list d then divides all
#elements by this no.
if len(d)==0:
return []
BIG=d[0]
#searching for the largest no.
for x in d:
if x>BIG:
BIG=x
if BIG==0:
return
#updating the list.
for i in range(len(d)):
d[i]=d[i]/BIG
return d
##checks wheather vertx v1 can connect with v2. (note: vi1 and vi2 are
##indices not the obeject itself.
##2 vertices are not connectable if while connecting them it crosses
##another edge.
def isConnectable(vert,vd,vi1,vi2):
for vli in range(len(vd)):
#if vli==vi1 or len(vd[vli])==0:
if len(vd[vli])==0:
continue
for i in vd[vli]:
x1=vert[vli].co.x
y1=vert[vli].co.y
x2=vert[i].co.x
y2=vert[i].co.y
x3=vert[vi1].co.x
y3=vert[vi1].co.y
x4=vert[vi2].co.x
y4=vert[vi2].co.y
if (x2-x1)==0:
k1=INFINITE
else:
k1=(y2-y1)/(x2-x1)
if (x4-x3)==0:
k2=INFINITE
else:
k2=(y4-y3)/(x4-x3)
if k1==k2:
continue
if (x1,y1)==(x3,y3) or (x1,y1)==(x4,y4)\
or (x2,y2)==(x3,y3) or (x2,y2)==(x4,y4):
continue
x=(y3-y1+k1*x1-k2*x3)/(k1-k2)
y=y1+k1*(x-x1)
flag=0
if x1<x2:
X1,X2=x1,x2
else:
X1,X2=x2,x1
if y1<y2:
Y1,Y2=y1,y2
else:
Y1,Y2=y2,y1
if X1<=x and x<=X2 and Y1<=y and y<=Y2:
if DEBUG:
print '+++no Connection for '+str(vi1)+' and '+str(vi2)+'+++'
print '+++>x within x1x2 of vert.s '+str(vli)+' and '+str(i)
flag=1
if x3<x4:
X1,X2=x3,x4
else:
X1,X2=x4,x3
if y3<y4:
Y3,Y4=y3,y4
else:
Y3,Y4=y4,y3
if X1<x and x<X2 and Y1<=y and y<=Y2:
if DEBUG:
print '+++no Connection for '+str(vi1)+' and '+str(vi2)+'+++'
print '+++>x within x1x2 of vert.s '+str(vli)+' and '+str(i)
flag+=1
if flag==2:
return False
return True
def vert2face():
selection = Object.GetSelected()
if len(selection) == 0:
error('No object selected')
return
if len(selection)>1:
error('Select only one object')
return
if selection[0].getType() != 'Mesh':
error('Only mesh are allowed.')
return
obj=selection[0].getData() #getting the object.
#getting list of all selected vertices.
vert=[]
for v in obj.verts:
if v.sel:
vert.append(v)
#Hence for revision.
#ob is the mesh object.
#vert is the list of selected vertices.
if DEBUG:
print "==Vertices data dump=="
i=0
for v in vert:
i=i+1
print "vert "+str(i)+" ("+str(v.co.x)+","+str(v.co.y)+")"
print("==Dump complete==")
#calculating distances of each vertice with every other.
#c=[]
stdDev=[]
for i in range(len(vert)):
r=[]
for j in range(len(vert)):
if i==j: continue
r.append(calDis(vert[i],vert[j]))
r=rationalizeDis(r)
if r is None:
error('Maybe faulty mesh. Two vertices in the same location.')
return
stdDev.append([calStdDeviation(r),i])
#c.append(r)
#bubble sorting stdDev according to increasing values.
for i in range(len(stdDev)):
for j in range(i+1,len(stdDev)):
if stdDev[i][0]>stdDev[j][0]:
t=stdDev[i]
stdDev[i]=stdDev[j]
stdDev[j]=t
if DEBUG:
print '@@stdDev dump@@'
for s in stdDev:
print s
print '@@Dump complete@@'
#sorting vert according to increasing stdDev.
tvert=[]
for sd in stdDev:
tvert.append(vert[sd[1]])
vert=tvert
tvert=[]#clearing it
stdVert=[]#clearing it
vd=[] #stores index of all the vertices a particular vertex is connected to.
#first searching and updating vd of already connected vertices.
for i in range(len(vert)):
r=[]
for j in range(i+1,len(vert)):
if obj.findEdge(vert[i],vert[j]) is not None:
r.append(j)
vd.append(r)
if DEBUG:
print '**vd dump (of already connected vertices)**'
for v in vd:
print v
print '**Dump complete**'
#now connecting vertices.
for i in range(len(vert)):
for j in range(i+1,len(vert)):
if vd[i].count(j)==0 and isConnectable(vert,vd,i,j):
vd[i].append(j)
if DEBUG:
print '**vd dump (Final)**'
for v in vd:
print v
print '**Dump complete**'
#making faces.:-)
vertexList=[]
for vi in range(len(vd)):
vil=vd[vi]
for i in vil:
for j in vil:
if i==j:
continue
if vd[i].count(j)!=0: #means vert[i] is connected with vert[j].
vertexList.append([vert[vi],vert[i],vert[j]])
if DEBUG: print '++vertexList dump++'
face=[]
for vL in vertexList:
face.append(NMesh.Face(vL))
if DEBUG:
print [(vL[0].co.x ,vL[0].co.y),(vL[1].co.x ,vL[1].co.y),(vL[2].co.x ,vL[2].co.y)]
if DEBUG: print '++Dump complete++'
#updating obj.
#obj.addEdgesData()
for f in face:
obj.addFace(f)
obj.update()
##calling vert2face##
Window.DrawProgressBar(0.0, 'Vertices to Faces v apha1 ')
print 'Vertices to Faces v apha1. Processing...'
is_editmode = Window.EditMode()
if is_editmode: Window.EditMode(0)
vert2face()
if is_editmode: Window.EditMode(1)
print 'Done!'
Window.DrawProgressBar(1.0, '')
Do write ur comments. And someone more knowledgeable if u think this script is worth ur time then help me improve it.
I hope this is useful.