# for http://blender.stackexchange.com/questions/40704/scaling-only-the-height-of-a-parallelogram-plane
__author__ = 'thoth'
import bpy
from mathutils import *
def share_vertex(e, horiz_edge):
return e.vertices[0] in horiz_edge.vertices or e.vertices[1] in horiz_edge.vertices
def horiz_score(vector, axis):
v2 = vector.copy()
v2[axis]=0
dz = abs(vector[axis])
if dz >0:
return v2.magnitude/ dz
else:
return float('inf')
def most_horizontal_edge(obj, axis):
mesh = obj.data
global_verts = [ obj.matrix_world*v.co for v in mesh.vertices ]
score = None
rval = None
for e in mesh.edges:
v1 = global_verts[e.vertices[0]]
v2 = global_verts[e.vertices[1]]
s2 = horiz_score(v2-v1, axis)
if (score is None or s2 > score):
score = s2
rval = e
return rval
def scale_parallelogram(obj, factor, axis):
mesh = obj.data
horiz_edge = most_horizontal_edge(obj, axis)
global_verts = [ obj.matrix_world*v.co for v in mesh.vertices ]
if True:
other_verts = set(range(len(global_verts)))
other_verts.difference_update(horiz_edge.vertices)
else:
other_verts = set()
for e in mesh.edges:
if share_vertex(e, horiz_edge):
continue
other_verts.update(e.vertices)
#print("%r -vs- %r"%(horiz_edge.vertices[:], other_verts))
z1 = [ global_verts[i][axis] for i in horiz_edge.vertices]
z2 = [ global_verts[i][axis] for i in other_verts]
z_all = [ v[axis] for v in global_verts ]
delta_z =max(z_all)-min(z_all)
z_change = 0.5*(1-factor)*delta_z
delta_v = Vector([0,0,0])
delta_v[axis] = z_change
#print(global_verts[0])
mwi = obj.matrix_world.inverted()
if (min(z1) < min(z2)):
delta_v = -delta_v
for i in horiz_edge.vertices:
mesh.vertices[i].co = mwi * (global_verts[i] - delta_v)
for i in other_verts:
mesh.vertices[i].co = mwi * (global_verts[i] + delta_v)
#print(mesh.vertices[0].co)
mesh.update()
#
#
x_axis=0
y_axis=1
z_axis=2
for obj in bpy.context.selected_objects:
scale_parallelogram(obj, 0.5, z_axis)
|
Blender python API quick-start
Syntax highlighting by Pygments.