How to add points to a grease pencil stroke (or make new one) with python script?

I want to draw script-calculated curves with the grease pencil. Using this line of python I'm able to redefine the points of an existing stroke, shown below.

So far I can't add a point like this:

newpt = points[200].copy()  # error
points.append(newpt)        # error


or this:

points.items().append('put various things here')   # NO error, but no new points either


where:

points = bpy.data.grease_pencil[0].layers[0].active_frame.strokes[0].points


So instead, I draw a big scribble, find out the length using the interactive python window (in this case it's 427) and then make a new set of coordinates of the same length.

How can I create or at least increase the number of points of a grease pencil stroke? I'm looking for something similar to the way I can make new mesh objects:

# example: make a new mesh object - I wish I could make grease pencil objects like this!!!
newmesh = bpy.data.meshes.new('Newmesh')
newobj  = bpy.data.objects.new('Newobj', newmesh)

newmesh.from_pydata(verts, [], faces)


import numpy as np
import bpy

pi, twopi = np.pi, 2*np.pi

theta = np.linspace(0, 20*twopi, 427)
theta -= theta.mean()

r = 4 - 2*np.cos(0.1*theta)

y = theta / twopi
x = r*np.cos(theta)
z = r*np.sin(theta)

krazy_koil_points = np.vstack((x, y, z)).T

points = bpy.data.grease_pencil[0].layers[0].active_frame.strokes[0].points
for i, point in enumerate(points):
point.co = krazy_koil_points[i]


Same thing, but without numpy:

import bpy, math

pi, twopi = math.pi, 2*math.pi

theta = [20*twopi * i / 427. for i in range(427)]

mean  = sum(theta)/float(len(theta))

theta = [th - mean for th in theta]

r = [4 - 2*math.cos(0.1*th) for th in theta]

y = [th/twopi for th in theta]
x = [a*math.cos(b) for a, b in zip(r, theta)]
z = [a*math.sin(b) for a, b in zip(r, theta)]

krazy_koil_points = list(zip(x, y, z))

points = bpy.data.grease_pencil[0].layers[0].active_frame.strokes[0].points
for i, point in enumerate(points):
point.co = krazy_koil_points[i]


What you're looking for is the add method within the points collection.

EDITED: Fixed script to work with fresh clean files that have no grease pencil data.

import bpy, math

S  = bpy.context.scene

# Create grease pencil data if none exists
if not S.grease_pencil:
a = [ a for a in bpy.context.screen.areas if a.type == 'VIEW_3D' ][0]
override = {
'scene'         : S,
'screen'        : bpy.context.screen,
'object'        : bpy.context.object,
'area'          : a,
'region'        : a.regions[0],
'window'        : bpy.context.window,
'active_object' : bpy.context.object
}

gp = S.grease_pencil

# Reference grease pencil layer or create one of none exists
if gp.layers:
gpl = gp.layers[0]
else:
gpl = gp.layers.new('gpl', set_active = True )

# Reference active GP frame or create one of none exists
if gpl.frames:
fr = gpl.active_frame
else:
fr = gpl.frames.new(1)

# Create a new stroke
str = fr.strokes.new()
str.draw_mode = '3DSPACE'

# Number of stroke points
strokeLength = 500

pi, twopi = math.pi, 2*math.pi

theta = [20 * twopi * i / strokeLength for i in range(strokeLength)]

mean  = sum(theta)/float(len(theta))

theta = [th - mean for th in theta]

r = [4 - 2*math.cos(0.1*th) for th in theta]

y = [th/twopi for th in theta]
x = [a*math.cos(b) for a, b in zip(r, theta)]
z = [a*math.sin(b) for a, b in zip(r, theta)]

krazy_koil_points = list(zip(x, y, z))

points = str.points
for i, point in enumerate(points):
points[i].co = krazy_koil_points[i]

• Thanks :) Weird though, I use 2.74 here as well and it did work. Curious to see the errors you ran into. – TLousky Mar 17 '16 at 15:00
• Found the issue, fixing the script in a min (no grease pencil data exists, you can fix it manually by creating adding a grease pencil layer, but I'll check for it in the script and add it there too). – TLousky Mar 17 '16 at 15:03
• @uhoh, fixed it, please have another go. – TLousky Mar 17 '16 at 15:13
• Hey super! This is exactly what I need! I like your answers - they are always concise and yet complete with running script. Thanks for your time and persistence :) – uhoh Mar 17 '16 at 15:36
• oh, I was so happy to see this work that I forgot to accept the answer @@ thanks! – uhoh Mar 17 '16 at 16:27