# Using grease pencils to draw programmatically. Should I have many grease pencil objects---many or one?

I have the following code to draw a black grease pencil line segment, from the points [0, 0, 0] to [1, 1, 0]:

from typing import Tuple

from bpy.types import GreasePencil, GPencilLayer, GPencilFrame, GPencilStroke
import bpy

def create_gp(gp_data: GreasePencil, name) -> GreasePencil:
if name not in bpy.context.scene.objects:
gp_obj = bpy.data.objects.new(name, gp_data)
bpy.context.scene.objects[-1].name = name

return bpy.context.scene.objects.get(name)

def create_gp_layer(gp_obj, layer_name, clear_layer) -> GPencilLayer:
# Get grease pencil layer or create one if none exists
if layer_name in gp_obj.data.layers:
gp_layer = gp_obj.data.layers.get(layer_name)
else:
gp_layer = gp_obj.data.layers.new(layer_name, set_active=True)

if clear_layer:
gp_layer.clear()

return gp_layer

def init_gp(name) -> Tuple[GreasePencil, GreasePencil]:
gp_data = bpy.data.grease_pencils.new(name)
gp_obj = create_gp(gp_data, name)

return gp_data, gp_obj

def stroke_polyline(gp_frame: GPencilFrame, vertices, line_width) -> GPencilStroke:
gp_stroke = gp_frame.strokes.new()

for ix, vertex in enumerate(vertices):
gp_stroke.points[ix].co = vertex

gp_stroke.line_width = line_width
return gp_stroke

def create_gp_material(name: str, color) -> bpy.types.Material:
gp_mat = bpy.data.materials.new(name)
bpy.data.materials.create_gpencil_data(gp_mat)
gp_mat.grease_pencil.color = color

return gp_mat

gp_dat, gp_obj = init_gp("TestPencil")
gp_layer = create_gp_layer(gp_obj, "TestLayer", True)
gp_frame = gp_layer.frames.new(0)
gp_mat = create_gp_material("BlackLine", [0., 0., 0., 1.])
gp_dat.materials.append(gp_mat)
gp_stroke = stroke_polyline(gp_frame, [[0, 0, 0], [1, 1, 0]], 10)

print("Success!")



It produces the following output:

So far, so good. Now, I want to draw lots of different things, on many different layers, each with many different frames, etc. This will require proper management of the grease pencil objects, but since I put together this code by scrounging around on the internet, I do not understand some of the central concepts.

1. What is the difference between gp_dat, and gp_obj? Both have type GreasePencil, so why is it that gp_dat has a materials attribute, but gp_obj does not? Why do they need to be linked together by the bpy.context.scene.collection.objects.link(gp_obj) instruction? (I learned I must do this from: Creating a Grease Pencil Material in Blender 2.8)

2. Assuming I have only one Blender scene, how many gp_dat/gp_obj pairs should one create? I think I could do all my drawing using only one grease pencil object, with many associated materials. (Although, I haven't yet figured out how to assign a particular material to a drawing instruction.) So, under what circumstances will I need to create multiple grease pencil objects?

• gp_data is the data of the gp_obj, and you are linking the object to the scene and not to the data. you can get the material from obj with bpy.context.selected_objects[0].data.materials[0] – Alex bries Nov 4 '20 at 9:45