# Editing a mesh in proportional mode from script

I'm trying to set the location of vertices in a mesh from a python script. No problems setting the location, however I'd like connected vertices within a certain range to also move proportionally.

I only need to move vertices in the positive Z direction. The mesh is a just an evenly subdivided XY plane (eg. a grid of vertices).

This screenshot shows a normal proportional edit on the left, size 0.25, and the script result on the right:

Here's the code I've tried so far. It runs, but has no proportional effect on the connected vertices (just the selected random vertex):

bpy.context.scene.tool_settings.proportional_edit="CONNECTED"
bpy.context.scene.tool_settings.use_proportional_edit_objects = True
bpy.context.scene.tool_settings.proportional_size=50

# Set the Z coordinate of 10 random vertices in the plane

for v in range(10):
SetVertexGlobal("WaterPlane",random.randint(0,289),[None,None,1.25])

bpy.context.scene.tool_settings.use_proportional_edit_objects = False
bpy.context.scene.tool_settings.proportional_edit="DISABLED"


The SetVertexGlobal function is defined as:

def SetVertexGlobal(objectName,vertexIndex, targetLocation):
obj  = bpy.data.objects[objectName]
mesh = obj.data
vert = mesh.vertices[vertexIndex]
mat_world = obj.matrix_world

pos_world = mat_world * vert.co

if targetLocation[0] is not None:
pos_world.x =targetLocation[0]

if targetLocation[1] is not None:
pos_world.y =targetLocation[1]

if targetLocation[2] is not None:
pos_world.z =targetLocation[2]

vert.co = mat_world.inverted() * pos_world


## 1 Answer

As you can see from your result, simply adjusting the vertex location via script will not invoke proportional editing. The translate.transform operator has all the settings you need.

Here is a test script to add 10 random bumps to a grid already in edit mode.

import bpy
import bmesh
from random import randint

context = bpy.context

bm = bmesh.from_edit_mesh(context.edit_object.data)
# deselect all
for v in bm.verts:
v.select = False

for i in range(10):
transform = (0, 0, 1)
v = bm.verts[randint(0, len(bm.verts) - 1)]
v.select = True
bpy.ops.transform.translate(value=transform,
constraint_axis=(False, False, False),
constraint_orientation='GLOBAL',
mirror=False,
proportional='CONNECTED',
proportional_edit_falloff='SMOOTH',
proportional_size=1)
v.select = False


Adjust accordingly into methods etc to suit your requirements. Being an operator it needs to have context, To "dimple" multiple objects

for obj in multiple_objects:
scene.objects.active = obj  # make context
bpy.ops.object.mode_set(mode='EDIT')
#dimple(...)
bpy.ops.object.mode_set(mode='OBJECT')

• Thanks a lot. I tried bpy.ops.transform.translate() previously but could not get it working most likely due to an invalid context. – Ash Nov 2 '15 at 13:24