TO TEST THE 3 SCRIPTS CREATE A CUBE AND SUBDIVIDE IT 2 OR 3 TIMES,PASTE THE SCRIPT AND RUN IT
Ok, I’ve advanced a lot. First I made a script that looped through all the mesh’s verts in sets of 3 verts. If the 3 verts were colinear the 2 edges that they formed were parallel. I would then find the “middle one” and join it to the closest vert of the other 2.
# -*- coding: utf-8 -*-
import Blender
from Blender import Object
import math
Blender.Window.WaitCursor(1)
EditMode = Blender.Window.EditMode()
if EditMode: Blender.Window.EditMode(0)
me = Object.GetSelected()[0].getData(mesh=1)
### Print Object Coordinates and set vertlist
print me.name, "is being processed by Mesh Optimizer:"
vertlist = [v.co[:] for v in me.verts]
#vertlist = [v.co[:] for v in me.verts if v.sel]
### Round vert coordinates
for i in range(0,len(vertlist)):
for s in range(0,len(vertlist[i])):
vertlist[i][s] = float("%0.2f" % (vertlist[i][s]))
def middlePoint(A,B,C):
MiddlePoint=[]
x=[A[0],B[0],C[0]]
y=[A[1],B[1],C[1]]
z=[A[2],B[2],C[2]]
x.sort()
y.sort()
z.sort()
p=["a","b","c"]
pco=[A,B,C]
for n in range(0,3):
if x[1]==pco[n][0] and y[1]==pco[n][1] and z[1]==pco[n][2]:
MiddlePoint=p[n]
break
return MiddlePoint
def Mod(vector): #Modulo of vector
global math
return math.sqrt(abs(vector[0]**2 + vector[1]**2 + vector[2]**2))
def Prod_Esc(v1,v2):
global Mod
ProEsc = (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])/(Mod(v1)*Mod(v2))
try:return math.acos(ProEsc)
except ValueError:return 0
def vert_merge(AB,AC):
global me,a,b,c,middlePoint,A,B,C
if Mod(AB) < Mod(AC):
if middlePoint(A,B,C) == "b":
me.verts[b].co[:]=me.verts[a].co[:]
else: me.verts[a].co[:]=me.verts[b].co[:]
else:
if middlePoint(A,B,C) == "b":
me.verts[b].co[:]=me.verts[c].co[:]
else: me.verts[c].co[:]=me.verts[b].co[:]
#################################################################
#################################################################
for a in range(0,len(vertlist)-2):
for b in range(a+1,len(vertlist)-1):
for c in range(b+1,len(vertlist)):
Blender.Window.EditMode(0)
A = vertlist[a]
B = vertlist[b]
C = vertlist[c]
AB = [B[0]-A[0],B[1]-A[1],B[2]-A[2]]
AC = [C[0]-A[0],C[1]-A[1],C[2]-A[2]]
if AB != [0,0,0] and AC != [0,0,0] and Prod_Esc(AB,AC) == 0:
if AB is not AC:
vert_merge(AB,AC)
Blender.Window.EditMode(1)
Blender.Window.RedrawAll()
me.remDoubles(0.001)
if EditMode: Blender.Window.EditMode(1)
Blender.Window.WaitCursor(0)
That’s the result I want however if you look carefully the mesh is not very good, there are redundant overlapping faces (a square on top of a triangle, etc.)
I suspected this was from not checking if the sets of 3 verts were adjacent, so, I started using edges to test ONLY sets of 3 adjacent verts. First I created this script that is the prototype to check all the edges:
# -*- coding: utf-8 -*-
import Blender
from Blender import Object
import math
Blender.Window.WaitCursor(1)
EditMode = Blender.Window.EditMode()
if EditMode: Blender.Window.EditMode(0)
me = Object.GetSelected()[0].getData(mesh=1)
def select_adjacent_edges(v1):
global me
for i in me.edges:
if i.key[0]==v1 or i.key[1]==v1: i.sel=1
##################
##################
i=0
edges_number=len(me.edges)
while i < edges_number:
Blender.Window.EditMode(0)
me.sel=0
me.edges[i].sel=1
select_adjacent_edges(me.edges[i].key[0])
select_adjacent_edges(me.edges[i].key[1])
Blender.Window.EditMode(1)
Blender.Window.RedrawAll()
i+=1
Blender.Window.EditMode(0)
and it correctly loops through all the edges so I went to apply the algoritm on top of that. It goes like this:
1-start on edge 0 - the variable is “e”
2-A is edge’s first vert and B is the edge’s 2nd vert
3-Find all the verts that are adjacent to B but excluding vert A and B and save the result in c_list
4-Now, the point C will be looped inside the c_list so that we are always testing A,B and C-(all the B’s adjacent verts)
5-if A,B and C are parallel, knowing that they are all adjacent thanks to the previous steps, we can now merge the B(always the middle vert) with the closest vert (A or C)
6-go to the next edge
# -*- coding: utf-8 -*-
import Blender
from Blender import Object
import math
Blender.Window.WaitCursor(1)
EditMode = Blender.Window.EditMode()
if EditMode: Blender.Window.EditMode(0)
me = Object.GetSelected()[0].getData(mesh=1)
### Print Object Coordinates and set vertlist
print me.name, "is being processed by Mesh Optimizer:"
vertlist = [v.co[:] for v in me.verts]
#vertlist = [v.co[:] for v in me.verts if v.sel]
def Round(number):
return float("%0.2f" % number)
def Mod(vector): #Modulo of vector
global math
return math.sqrt(abs(vector[0]**2 + vector[1]**2 + vector[2]**2))
def Prod_Esc(v1,v2):
global Mod
ProEsc = (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])/(Mod(v1)*Mod(v2))
try:return math.acos(ProEsc)
except ValueError:return 0
def vert_merge(AB,AC):
global me,a,b,c,middlePoint,A,B,C
if Mod(AB) < Mod(AC):
me.verts[b].co[:] = me.verts[a].co[:]
else:
me.verts[b].co[:]=me.verts[c].co[:]
def select_adjacent_edges(v1):
global me
for i in me.edges:
if i.key[0]==v1 or i.key[1]==v1: i.sel=1
def complementar2nd_verts(v1,v2):
global me,select_adjacent_edges
me.sel=0
select_adjacent_edges(v2)
adj_edges=me.edges.selected()
adj_verts=[]
for edge in xrange(len(adj_edges)):
p1 = me.edges[edge].key[0]
p2 = me.edges[edge].key[1]
if p1 != v2 and p1 != v1 and p1 not in adj_verts: adj_verts.append(p1)
if p2 != v2 and p2 != v1 and p2 not in adj_verts: adj_verts.append(p2)
return adj_verts
#################################################################
#################################################################
e=0
edges_number=len(me.edges)
print edges_number
while e < edges_number:
Blender.Window.EditMode(0)
a = me.edges[e].key[0]
A = [Round(me.edges[e].v1.co[0]),Round(me.edges[e].v1.co[1]),Round(me.edges[e].v1.co[2])]
b = me.edges[e].key[1]
B = [Round(me.edges[e].v2.co[0]),Round(me.edges[e].v2.co[1]),Round(me.edges[e].v2.co[2])]
c_list = complementar2nd_verts(a,b)
for c in c_list:
C = [Round(me.verts[c].co[0]),Round(me.verts[c].co[1]),Round(me.verts[c].co[2])]
AB = [B[0]-A[0],B[1]-A[1],B[2]-A[2]]
AC = [C[0]-A[0],C[1]-A[1],C[2]-A[2]]
if AB != [0,0,0] and AC != [0,0,0] and Prod_Esc(AB,AC) == 0:
if AB is not AC:
vert_merge(AB,AC)
Blender.Window.EditMode(1)
Blender.Window.RedrawAll()
e+=1
print "DONE!!!"
Blender.Window.EditMode(0)
me.remDoubles(0.001)
if EditMode: Blender.Window.EditMode(1)
Blender.Window.WaitCursor(0)
The problem is that only some edges are being looped even though the prototype worked perfectly and I don’t know why. Could someone help? Try this last script with a cube subdivided 3 or 4 times to see what I’m talking about.