(Please scroll down for a script that works)
Someone asked how to remove a vertex from the middle of an edge while keeping the uv mapping intact, https://blenderartists.org/forum/viewtopic.php?t=32961
In fact that should be the default behavior of the merge vertex tool, I think, only a few more lines of code would be needed.
I thought I could use such a tool, because after many repeated removals of vertices using merge tool, the uv map gets totally ruined. So I came with this little script which works like the ‘at cursor’ option of the merge tool (alt-m), first selecting the vertex where the merging will happen, then placing the cursor (shift-s) on this vertex and then selecting the vertices which are to be removed.
Take for example, this:
Which after three merge operations becomes a cleaner object, while keeping the textures:
However it only works for objects for wich size and rotation have been applied, and I i don’t know how to convert the global cursor position into local object coordinates. If anyone knows how to do that, I will appreciate your help.
import Blender
fpu= 1.0/65536
Blender.Window.EditMode(0)
curspos=Blender.Window.GetCursorPos()
ob=Blender.Object.GetSelected()
if len(ob)==1:
if ob[0].getType()=='Mesh':
mesh=ob[0].getData()
# Is there a way to quikly get selected vertices?
merged=[]
mergepoint=0
#Find vertex at cursor position.
for vrt in mesh.verts:
if vrt.sel:
if abs(vrt.co[0]-curspos[0])<fpu:
if abs(vrt.co[1]-curspos[1])<fpu:
if abs(vrt.co[2]-curspos[2])<fpu:
mergepoint=vrt
#Or other selected vertices.
else:
merged.append(vrt)
faces1=[]
faces2=[]
if (mergepoint!=0)&(len(merged)):
for face in mesh.faces:
for v in merged:
if (v in face.v)&(mergepoint not in face.v):
faces2.append((face,v))
if mergepoint in face.v:
faces1.append(face)
#List of deletable vertices and faces.
remverts=[]
remfaces=[]
for face1 in faces1:
for face2 in faces2:
v2=face2[1]
if v2 in face1.v:
#Another common vertex is needed to know if faces are adjacent.
common=0
for v in face2[0].v:
if v==v2:
continue
if v in face1:
common=1
if common:
i1=face1.v.index(mergepoint)
i2=face2[0].v.index(v2)
#Tampering with face vertices seems to be dangerous, so use copies.
fv0=face1.v[:]
fv2=face2[0].v[:]
#Remove vertex from both polygons.
fv0.remove(v2)
fv2.remove(v2)
if v2 not in remverts:
remverts.append(v2)
#Insert vertex at cursor to substitute old vertex.
fv2.insert(i2,mergepoint)
#Remove vertex from face containing merge point
if len(fv0)>2:
f1=Blender.NMesh.Face(fv0)
mesh.faces.append(f1)
f1.mode=face1.mode
f1.transp=face1.transp
f1.col=face1.col
if face1.image:
f1.image=face1.image
if len(face1.uv)!=0:
uv=face1.uv[:]
uv.pop(face1.v.index(v2))
f1.uv=uv
if face1 not in remfaces:
remfaces.append(face1)
f2=Blender.NMesh.Face(fv2)
mesh.faces.append(f2)
f2.mode=face2[0].mode
f2.transp=face2[0].transp
f2.col=face2[0].col
if face2[0].image:
f2.image=face2[0].image
if len(face2[0].uv)!=0:
uv=face2[0].uv[:]
#Insert uv vertex
uv.insert(i2,face1.uv[face1.v.index(mergepoint)])
#Remove old value
uv.pop(i2+1)
f2.uv=uv
mesh.faces.remove(face2[0])
for f in remfaces:
mesh.faces.remove(f)
for v in remverts:
mesh.verts.remove(v)
mesh.update()
Blender.Window.EditMode(1)