3
$\begingroup$

I like how gpencil lets me draw shapes and link the data to specific objects or the scene. I have a trigonometry script which generates shapes, but I can't seem to select which 'Data to be linked' from a script.

enter image description here

The following script is a reduced version of what i'm doing, but it shows that the layer and data creation is easy enough.

import math
import bpy


def get_layer(gdata_owner, layer_name):

    grease_data = bpy.data.grease_pencil
    if gdata_owner not in grease_data:
        gp = grease_data.new(gdata_owner)
    else:
        gp = grease_data[gdata_owner]

    # get grease pencil layer
    if not (layer_name in gp.layers):
        layer = gp.layers.new(layer_name)
        layer.frames.new(1)
        layer.line_width = 1
    else:
        layer = gp.layers[layer_name]
        layer.frames[0].clear()

    return layer


def generate_gp3d_stroke(layer):
    layer.show_points = True
    layer.color = (0.2, 0.90, .2)
    s = layer.frames[0].strokes.new()
    s.draw_mode = '3DSPACE'

    chain = []
    num_verts = 10
    r = 2.2
    gamma = 2 * math.pi / num_verts
    for i in range(num_verts+1):
        theta = gamma * i
        world_point = (math.sin(theta) * r, math.cos(theta) * r, 1.2)
        chain.append(world_point)

    s.points.add(len(chain))
    for idx, p in enumerate(chain):
        s.points[idx].co = p


class TrigGenerator(bpy.types.Operator):

    bl_idname = 'mesh.trig_generator'
    bl_label = 'generated trig with gpencil'
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        obj = bpy.context.object
        data_name = 'stack_data'
        layer_name = "stack layer"
        layer = get_layer(data_name, layer_name)
        generate_gp3d_stroke(layer)
        return {'FINISHED'}


def register():
    bpy.utils.register_class(TrigGenerator)


def unregister():
    bpy.utils.unregister_class(TrigGenerator)


if __name__ == '__main__':
    register()

it's probably simple, but it eludes me.


update:

the one line fix is the last line of execute:

def execute(self, context):
    obj = bpy.context.object
    data_name = 'stack_data'
    layer_name = "stack layer"
    layer = get_layer(data_name, layer_name)
    generate_gp3d_stroke(layer)
    context.scene.grease_pencil = bpy.data.grease_pencil[data_name]
    return {'FINISHED'}
$\endgroup$

2 Answers 2

5
$\begingroup$

I'm not sure if this is what you are looking for but:

bpy.context.scene.grease_pencil = bpy.data.grease_pencil['GPencil']

will set the scene's active grease pencil datablock to be 'GPencil'.

I found this by using autocomplete in the Python Console to see properties of the Scene.

As with other datablocks in blender you can also set scene.grease_pencil to be None to have no active grease pencil datablock.

$\endgroup$
3
  • $\begingroup$ yep, that's the one. bpy.context.scene.grease_pencil = bpy.data.grease_pencil['stack_data'] $\endgroup$
    – zeffii
    Commented Apr 14, 2015 at 13:55
  • $\begingroup$ woah, I didn't thank you. Thanks! I must be very dim sometimes. $\endgroup$
    – zeffii
    Commented Apr 14, 2015 at 14:13
  • $\begingroup$ @zeffii No problem, everyone needs help sometimes. $\endgroup$ Commented Apr 14, 2015 at 14:52
1
$\begingroup$

Grease pencil can be attached either scene or object. Change grease pencil source from scene to object.

bpy.context.object.grease_pencil = bpy.context.scene.grease_pencil

Then you can select grease pencil setting. The code below set parent for the first layer.

bpy.context.object.grease_pencil.layers[0].parent = bpy.object.context
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .