I want to duplicate a selected edge and translate it to another location, based on the normal direction.

(source: shshop.da.to)

This is my current code:

import bpy
import mathutils
import math

obj = bpy.context.object
me = obj.data
eg = me.edges[2]

nor1x = me.vertices[eg.key[0]].normal.x
nor1y = me.vertices[eg.key[0]].normal.y
nor1z = me.vertices[eg.key[0]].normal.z

nor2x = me.vertices[eg.key[1]].normal.x
nor2y = me.vertices[eg.key[1]].normal.y
nor2z = me.vertices[eg.key[1]].normal.z 

x = nor1x + nor2x
y = nor1y + nor2y
z = nor1z + nor2z

norSum = mathutils.Vector((x,y,z)) 
  • $\begingroup$ What is your question? Does the code nor work? $\endgroup$
    – maddin45
    May 29, 2014 at 21:56
  • 2
    $\begingroup$ Blender only uses faces to calculate vertex normals. It looks like you're expecting it to use edge connectivity $\endgroup$
    – ideasman42
    May 30, 2014 at 6:56

1 Answer 1


There are several normal directions, not sure what you actually desire. In your figure, it looks as if you want to translate to the average vertex normal direction, but only in 2D.

Here's a 3D example using the bmesh module:

import bpy
import bmesh

me = bpy.context.object.data
bm = bmesh.from_edit_mesh(me)

active_edge = None
for elem in reversed(bm.select_history):
    if isinstance(elem, bmesh.types.BMEdge):
        active_edge = elem
    raise Exception("No active edge!")

v1, v2 = active_edge.verts
#co1 = v1.co + v1.normal
#co2 = v2.co + v2.normal
n = (v1.normal + v2.normal) * 0.5
co1 = v1.co + n
co2 = v2.co + n

ret = bmesh.ops.duplicate(bm, geom=[active_edge])
new_verts = [elem for elem in ret['geom'] if isinstance(elem, bmesh.types.BMVert)]

# Order???
new_verts[0].co = co1
new_verts[1].co = co2

  • $\begingroup$ We would be happy if you shared your final solution (edit your question to append it), and I if you accepted my answer :) $\endgroup$
    – CodeManX
    May 30, 2014 at 15:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .