2
$\begingroup$

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:

enter image description here

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
$\endgroup$
2
$\begingroup$

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')
|improve this answer|||||
$\endgroup$
  • $\begingroup$ Thanks a lot. I tried bpy.ops.transform.translate() previously but could not get it working most likely due to an invalid context. $\endgroup$ – Ash Nov 2 '15 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.