# Randomise vertices in xy-plane

I try to generate Cables with the Blender Python API. I got it mostly working but there is one detail I would like to change. I randomised the vertices of a Nurbs Path with bpy.ops.transform.vertex_random but the problem with that is that the vertices also get randomised in Z direction but I want them to be "flat" cables laying on the ground.

Has anyone a solution to this? Every kind of help is highly appreciated.

Thank you very much.

The Code:

import bpy
import math
import random
import bmesh

#define number of Cables
numberOfCables = 5
count = 0

#clean scene (delete all objects inside
def clean_scene():
for things in bpy.data.objects:
bpy.data.objects.remove(things)

clean_scene()
#bpy.ops.object.select_all(action='SELECT')
#bpy.ops.object.delete(use_global=False, confirm=False)

#Main Programm
for i in range(numberOfCables):

#define random values for location and size
X = random.uniform(0,5)
Y = random.uniform(0,5)
randomRadius = random.randrange(15,50,5)/10000 #random thickness ranging from 3mm to 8mm
randomLength = random.uniform(0.3,1) #random length ranging from 30cm to 1m
randomSeed = random.uniform(0,10)

#create Nurbs_Path
def create_Nurbs():
enter_editmode = True,
location=(X,Y,1))
return bpy.context.object

obj = create_Nurbs()

#randomly place vertecies to have different "cables"
bpy.ops.transform.vertex_random(offset=.5,
uniform=5,
normal=5,
seed=randomSeed,
wait_for_input=True)

bpy.ops.object.editmode_toggle()

• please show a bit more of your code snippet. Thanks. Normally you could just set z-Value to 0 after randomise or whatever value you wanna have. – Chris May 19 at 11:22
• I edited my question with the Code. Sorry for that. – SchmidtiT May 19 at 11:41

Change the value of NurbsObject().data.splines[a].points[b].co, checking points[b].select if you'd like to restrict to only currently selected points:

def AnisotropicRandomizePoints(scale=(1,1,1,0), points=None):
"""Anisotropically randomize the coordinates of NURBS points.
Accepts a sequence of length four as its first argument,
with the first three elements scaling the randomization
applied to X, Y, and Z coordinates and the fourth element
scaling the randomization applied to W respectively. Uses a
given list of points if specified, otherwise uses all selected
points in the active object if in Edit Mode or all points
in the active object otherwise."""
import random
import bpy
if points is None:
points = [p for s in bpy.context.object.data.splines for p in s.points if p.select or bpy.context.mode not in ('EDIT_CURVE', 'EDIT_SURFACE')]
points = [*points]
for p in points:
for i, v in enumerate(p.co):
p.co[i] = v + (random.random()*2-1)*scale[i]


(Do AnisotropicRandomizePoints(scale=(1,1,0,0)) to restrict randomisation to the XY plane.)

• Wow thank you for your help! That is exactly what I needed. And the results look very natural. – SchmidtiT May 20 at 8:44

Quick and dirty solution : Scale everything by 0 along Z axis, then Apply Scale.

Example :

import bpy

bpy.context.active_object.scale[2] = 0
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)

• Thank you very much! – SchmidtiT May 20 at 8:45