blender-grease-pencil
Create 2D art and animation in Blender using Grease Pencil and Python. Use when the user wants to draw strokes programmatically, create 2D animations, build Grease Pencil objects from code, manage GP layers and frames, apply GP modifiers, set up drawing guides, or script any Grease Pencil workflow in Blender.
What this skill does
# Blender Grease Pencil
## Overview
Create 2D drawings and animations in Blender's 3D space using the Grease Pencil system and Python. Build strokes from point data, manage layers and frames, apply GP-specific modifiers, and animate 2D content — all scriptable from the terminal.
## Instructions
### 1. Create a Grease Pencil object
```python
import bpy
# Create a new Grease Pencil data block and object
gp_data = bpy.data.grease_pencils.new("MyDrawing")
gp_obj = bpy.data.objects.new("MyDrawing", gp_data)
bpy.context.collection.objects.link(gp_obj)
# Or use the operator
bpy.ops.object.gpencil_add(type='EMPTY') # EMPTY, STROKE, MONKEY, SCENE, COLLECTION
gp_obj = bpy.context.active_object
```
Types for `gpencil_add`: `EMPTY` (blank), `STROKE` (single stroke), `MONKEY` (Suzanne in 2D), `SCENE` (draw over scene), `COLLECTION` (from collection).
### 2. Add layers and frames
```python
import bpy
gp_data = bpy.context.active_object.data
# Create a layer
layer = gp_data.layers.new("Outlines", set_active=True)
layer.info = "Outlines"
layer.blend_mode = 'REGULAR' # REGULAR, OVERLAY, ADD, SUBTRACT, MULTIPLY
layer.opacity = 1.0
layer.use_lights = False
# Create a keyframe on the layer at a specific frame
frame = layer.frames.new(frame_number=1)
# Additional layers for organization
color_layer = gp_data.layers.new("Colors", set_active=False)
color_frame = color_layer.frames.new(frame_number=1)
```
### 3. Draw strokes programmatically
```python
import bpy
gp_obj = bpy.context.active_object
gp_data = gp_obj.data
layer = gp_data.layers.active
frame = layer.frames[0] # or layer.active_frame
# Create a stroke
stroke = frame.strokes.new()
stroke.display_mode = '3DSPACE' # 3DSPACE, 2DSPACE, 2DIMAGE, SCREEN
stroke.line_width = 10
# Add points to the stroke
num_points = 5
stroke.points.add(num_points)
coords = [(0, 0, 0), (1, 0.5, 0), (2, 1, 0), (3, 0.5, 0), (4, 0, 0)]
for i, (x, y, z) in enumerate(coords):
stroke.points[i].co = (x, y, z)
stroke.points[i].pressure = 1.0 # pen pressure (0.0 - 1.0)
stroke.points[i].strength = 1.0 # color strength (0.0 - 1.0)
# Assign material index to stroke
stroke.material_index = 0
```
### 4. Create GP materials
```python
import bpy
gp_obj = bpy.context.active_object
# Solid fill material
mat_solid = bpy.data.materials.new("GP_Solid")
bpy.data.materials.create_gpencil_data(mat_solid)
mat_solid.grease_pencil.color = (0.1, 0.1, 0.1, 1.0) # stroke color
mat_solid.grease_pencil.fill_color = (0.8, 0.2, 0.2, 1.0) # fill color
mat_solid.grease_pencil.show_fill = True
mat_solid.grease_pencil.show_stroke = True
gp_obj.data.materials.append(mat_solid)
# Line-only material
mat_line = bpy.data.materials.new("GP_Line")
bpy.data.materials.create_gpencil_data(mat_line)
mat_line.grease_pencil.color = (0.0, 0.0, 0.0, 1.0)
mat_line.grease_pencil.show_fill = False
mat_line.grease_pencil.show_stroke = True
gp_obj.data.materials.append(mat_line)
```
### 5. Apply Grease Pencil modifiers
```python
import bpy
gp_obj = bpy.context.active_object
# Thickness modifier
thick = gp_obj.grease_pencil_modifiers.new("Thickness", 'GP_THICK')
thick.thickness_factor = 1.5
# Smooth modifier
smooth = gp_obj.grease_pencil_modifiers.new("Smooth", 'GP_SMOOTH')
smooth.factor = 0.5
smooth.step = 3
# Tint modifier (color shift)
tint = gp_obj.grease_pencil_modifiers.new("Tint", 'GP_TINT')
tint.color = (0.2, 0.5, 1.0)
tint.factor = 0.3
# Noise modifier (hand-drawn look)
noise = gp_obj.grease_pencil_modifiers.new("Noise", 'GP_NOISE')
noise.factor = 0.5
# Subdivide modifier (smoother curves)
subdiv = gp_obj.grease_pencil_modifiers.new("Subdivide", 'GP_SUBDIV')
subdiv.level = 2
# Build modifier (animated reveal)
build = gp_obj.grease_pencil_modifiers.new("Build", 'GP_BUILD')
build.mode = 'SEQUENTIAL' # SEQUENTIAL, CONCURRENT, ADDITIVE
build.start_frame = 1
build.length = 50
# Array modifier (repeat strokes)
array = gp_obj.grease_pencil_modifiers.new("Array", 'GP_ARRAY')
array.count = 5
array.offset = (1.0, 0.0, 0.0)
```
### 6. Animate Grease Pencil frame by frame
```python
import bpy
import math
gp_obj = bpy.context.active_object
gp_data = gp_obj.data
layer = gp_data.layers.active
total_frames = 24
for f in range(total_frames):
frame = layer.frames.new(frame_number=f + 1)
stroke = frame.strokes.new()
stroke.display_mode = '3DSPACE'
stroke.line_width = 8
# Animate a circle that grows
num_points = 32
stroke.points.add(num_points)
radius = 0.5 + (f / total_frames) * 2.0
for i in range(num_points):
angle = (2 * math.pi * i) / num_points
x = radius * math.cos(angle)
y = radius * math.sin(angle)
stroke.points[i].co = (x, y, 0)
stroke.points[i].pressure = 1.0
stroke.points[i].strength = 1.0
# Set playback range
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = total_frames
```
### 7. Configure drawing guides
```python
import bpy
# Guides are properties on the scene's tool settings
ts = bpy.context.scene.tool_settings
gp_settings = ts.gpencil_sculpt
# Access guide settings (when in Draw mode)
guide = ts.gpencil_stroke_placement_view3d
# Guide types are set via the tool settings
# Circular — concentric rings from reference point
# Radial — rays extending from reference point
# Parallel — constrained parallel lines
# Grid — horizontal/vertical grid lines
# Isometric — isometric angle constraints
# Note: Guides are interactive Draw mode features.
# For programmatic geometry, compute constrained points directly:
import math
def snap_to_grid(point, spacing=1.0):
return tuple(round(c / spacing) * spacing for c in point)
def snap_to_radial(point, center=(0, 0, 0), num_rays=8):
dx, dy = point[0] - center[0], point[1] - center[1]
angle = math.atan2(dy, dx)
snap_angle = round(angle / (2 * math.pi / num_rays)) * (2 * math.pi / num_rays)
dist = math.sqrt(dx**2 + dy**2)
return (center[0] + dist * math.cos(snap_angle),
center[1] + dist * math.sin(snap_angle),
point[2])
```
## Examples
### Example 1: Procedural comic panel with text
**User request:** "Create a simple comic panel layout with borders and speech bubble"
```python
import bpy
import math
def clear_scene():
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
clear_scene()
# Create GP object
gp_data = bpy.data.grease_pencils.new("ComicPanel")
gp_obj = bpy.data.objects.new("ComicPanel", gp_data)
bpy.context.collection.objects.link(gp_obj)
# Materials
mat_black = bpy.data.materials.new("GP_Black")
bpy.data.materials.create_gpencil_data(mat_black)
mat_black.grease_pencil.color = (0, 0, 0, 1)
mat_black.grease_pencil.show_fill = False
gp_obj.data.materials.append(mat_black)
mat_bubble = bpy.data.materials.new("GP_Bubble")
bpy.data.materials.create_gpencil_data(mat_bubble)
mat_bubble.grease_pencil.color = (0, 0, 0, 1)
mat_bubble.grease_pencil.fill_color = (1, 1, 1, 1)
mat_bubble.grease_pencil.show_fill = True
gp_obj.data.materials.append(mat_bubble)
# Panel border layer
border_layer = gp_data.layers.new("Borders")
border_frame = border_layer.frames.new(frame_number=1)
def draw_rect(frame, x, y, w, h, mat_idx=0, width=12):
stroke = frame.strokes.new()
stroke.display_mode = '3DSPACE'
stroke.line_width = width
stroke.material_index = mat_idx
stroke.points.add(5)
corners = [(x, y, 0), (x+w, y, 0), (x+w, y+h, 0), (x, y+h, 0), (x, y, 0)]
for i, co in enumerate(corners):
stroke.points[i].co = co
stroke.points[i].pressure = 1.0
stroke.points[i].strength = 1.0
# Outer border
draw_rect(border_frame, 0, 0, 6, 4)
# Inner panels (2 panels side by side)
draw_rect(border_frame, 0.2, 0.2, 2.7, 3.6)
draw_rect(border_frame, 3.1, 0.2, 2.7, 3.6)
# Speech bubble layer
bubble_layer = gp_data.layers.new("Bubbles")
bubble_frame = bubble_layer.frames.new(frame_number=1)
stroke = bubble_frame.strokes.new()
stroke.display_mode = '3DSPACE'
stroke.line_width = 6
strokeRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.