跳到正文
cccskills
免费在 GitHub 公开

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.

中文简介正在准备中。当前显示原文说明。

集成工具Blender
查看安装方法

包含的文件(2)

  • SKILL.md11.7 KB
  • _scores.json2.6 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Blender Grease Pencil

Overview

Create 2D drawings and animations in Blender's 3D space using Grease Pencil and Python. Build strokes from point data, manage layers and frames, apply Grease Pencil modifiers, and animate 2D content, all scriptable from the terminal.

This skill targets the Grease Pencil v3 API (Blender 5.x, checked against the 5.2 Python API reference). The old v2 API (gpencil_add, layer.info, stroke.points.add(), grease_pencil_modifiers, GP_THICK) no longer exists; scripts written for Blender 2.8-4.2 must be ported. In Blender 4.3-4.5 the v3 data-blocks lived in bpy.data.grease_pencils_v3; from 5.0 bpy.data.grease_pencils is v3.

Data model: a GreasePencil data-block has layers (and layer groups); a layer has frames keyed by frame number; each frame points to a drawing; a drawing holds strokes stored as curve and point attributes (position, radius, opacity, material_index, cyclic).

Instructions

1. Create a Grease Pencil object

import bpy

gp_data = bpy.data.grease_pencils.new("MyDrawing")
gp_obj = bpy.data.objects.new("MyDrawing", gp_data)   # obj.type == 'GREASEPENCIL'
bpy.context.collection.objects.link(gp_obj)

# Or use the operator
bpy.ops.object.grease_pencil_add(type='EMPTY')   # EMPTY, STROKE, MONKEY, LINEART_SCENE, LINEART_OBJECT, LINEART_COLLECTION
gp_obj = bpy.context.active_object

Prefer the data-level route in scripts: it works in --background mode and gives you an object with no pre-made layers or frames to trip over.

2. Add layers and frames

gp_data = gp_obj.data

layer = gp_data.layers.new("Outlines", set_active=True)   # the name is layer.name
layer.blend_mode = 'REGULAR'   # REGULAR, HARDLIGHT, ADD, SUBTRACT, MULTIPLY, DIVIDE
layer.opacity = 1.0
layer.use_lights = False

frame = layer.frames.new(1)    # raises if frame 1 already exists on this layer
drawing = frame.drawing        # the container for strokes

# Copy, move, or remove keyframes
layer.frames.copy(1, 12)
layer.frames.move(12, 13)
layer.frames.remove(13)

Layers can be grouped: gp_data.layer_groups and gp_data.layers.new(name, layer_group=group).

3. Draw strokes programmatically

Strokes are added with drawing.add_strokes(sizes) (one point count per stroke) and then filled through attributes. The Blender docs recommend the attributes API over drawing.strokes[n] for anything beyond small scripts, and warn that stroke slices become invalid after the point or curve count changes.

def add_stroke(drawing, points, radius=0.02, material_index=0, cyclic=False):
    attrs = drawing.attributes
    first_curve = attrs.domain_size('CURVE')
    first_point = attrs.domain_size('POINT')
    drawing.add_strokes([len(points)])

    pos = attrs["position"].data
    rad = attrs["radius"].data
    for i, co in enumerate(points):
        pos[first_point + i].vector = co
        rad[first_point + i].value = radius      # radius, not width: line width is about 2 * radius

    for name, kind, value in (("material_index", 'INT', material_index),
                              ("cyclic", 'BOOLEAN', cyclic)):
        attr = attrs.get(name) or attrs.new(name, kind, 'CURVE')   # created on demand
        attr.data[first_curve].value = value
    drawing.tag_positions_changed()

add_stroke(drawing, [(0, 0, 0), (1, 0.5, 0), (2, 1, 0), (3, 0.5, 0), (4, 0, 0)])

Radius is in scene units (default 0.01 is thin); use 0.02-0.05 for visible lines at normal camera distances. Points also carry opacity (0-1).

4. Create Grease Pencil materials

mat_solid = bpy.data.materials.new("GP_Solid")
bpy.data.materials.create_gpencil_data(mat_solid)
style = mat_solid.grease_pencil
style.color = (0.1, 0.1, 0.1, 1.0)          # stroke color
style.fill_color = (0.8, 0.2, 0.2, 1.0)     # fill color
style.show_stroke = True
style.show_fill = True
gp_obj.data.materials.append(mat_solid)     # slot index = stroke material_index

5. Apply Grease Pencil modifiers

Grease Pencil modifiers are ordinary object modifiers in v3: use obj.modifiers with GREASE_PENCIL_* types.

thick = gp_obj.modifiers.new("Thickness", 'GREASE_PENCIL_THICKNESS')
thick.thickness_factor = 1.5                 # use_uniform_thickness + thickness for a fixed value

smooth = gp_obj.modifiers.new("Smooth", 'GREASE_PENCIL_SMOOTH')
smooth.factor = 0.5
smooth.step = 3

tint = gp_obj.modifiers.new("Tint", 'GREASE_PENCIL_TINT')
tint.color = (0.2, 0.5, 1.0)
tint.factor = 0.3

noise = gp_obj.modifiers.new("Noise", 'GREASE_PENCIL_NOISE')   # hand-drawn wobble
noise.factor = 0.5

subdiv = gp_obj.modifiers.new("Subdivide", 'GREASE_PENCIL_SUBDIV')
subdiv.level = 2

build = gp_obj.modifiers.new("Build", 'GREASE_PENCIL_BUILD')   # animated reveal
build.mode = 'SEQUENTIAL'      # SEQUENTIAL, CONCURRENT, ADDITIVE
build.time_mode = 'FRAMES'     # FRAMES, DRAWSPEED, PERCENTAGE
build.length = 50              # frames the build runs
build.use_restrict_frame_range = True   # then frame_start / frame_end apply
build.frame_start = 1

array = gp_obj.modifiers.new("Array", 'GREASE_PENCIL_ARRAY')
array.count = 5
array.constant_offset = (1.0, 0.0, 0.0)   # also set use_constant_offset = True

Other types follow the same pattern: GREASE_PENCIL_OPACITY, GREASE_PENCIL_COLOR, GREASE_PENCIL_MIRROR, GREASE_PENCIL_OFFSET, GREASE_PENCIL_LINEART, and so on. Every modifier has layer, material and pass filters (tree_node_filter takes a layer name, material_filter a material).

6. Animate frame by frame

import math

layer = gp_obj.data.layers.new("Pulse")
total_frames = 24
for f in range(total_frames):
    drawing = layer.frames.new(f + 1).drawing
    radius = 0.5 + (f / total_frames) * 2.0
    ring = [(radius * math.cos(2 * math.pi * i / 32),
             radius * math.sin(2 * math.pi * i / 32), 0) for i in range(32)]
    add_stroke(drawing, ring, radius=0.03, cyclic=True)

scene = bpy.context.scene
scene.frame_start, scene.frame_end = 1, total_frames

Each frame owns an independent drawing. Frames hold until the next keyframe, so you only create frames where the drawing changes.

7. Drawing guides

Guides (circular, radial, parallel, grid, isometric) are interactive Draw-mode tools in the viewport and have no scripting entry point for generating strokes. In a script, compute constrained points yourself:

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]
    step = 2 * math.pi / num_rays
    angle = round(math.atan2(dy, dx) / step) * step
    dist = math.hypot(dx, dy)
    return (center[0] + dist * math.cos(angle), center[1] + dist * math.sin(angle), point[2])

Examples

Example 1: Procedural comic panel with a speech bubble

User request: "Create a simple comic panel layout with borders and a speech bubble, saved as a .blend"

import bpy, math

# add_stroke() from step 3 must be defined above this point
gp_data = bpy.data.grease_pencils.new("ComicPanel")
gp_obj = bpy.data.objects.new("ComicPanel", gp_data)
bpy.context.collection.objects.link(gp_obj)

mat_ink = bpy.data.materials.new("GP_Ink")
bpy.data.materials.create_gpencil_data(mat_ink)
mat_ink.grease_pencil.color = (0, 0, 0, 1)
mat_ink.grease_pencil.show_fill = False
gp_data.materials.append(mat_ink)            # index 0

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_data.materials.append(mat_bubble)         # index 1

def rect(x, y, w, h):
    return [(x, y, 0), (x + w, y, 0), (x + w, y + h, 0), (x, y + h, 0)]

borders = gp_data.layers.new("Borders").frames.new(1).drawing
add_stroke(borders, rect(0, 0, 6, 4), radius=0.05, cyclic=True)
add_stroke(borders, rect(0.2, 0.2, 2.7, 3.6), radius=0.03, cyclic=True)
add_stroke(borders, rect(3.1, 0.2, 2.7, 3.6), radius=0.03, cyclic=True)

bubble = gp_data.layers.new("Bubbles").frames.new(1).drawing
ellipse = [(4.5 + 0.8 * math.cos(2 * math.pi * i / 24), 3.0 + 0.4 * math.sin(2 * math.pi * i / 24), 0.01)
           for i in range(24)]
add_stroke(bubble, ellipse, radius=0.025, material_index=1, cyclic=True)

bpy.ops.wm.save_as_mainfile(filepath="/tmp/comic_panel.blend")

Result: /tmp/comic_panel.blend with two layers ("Borders" with three rectangles, "Bubbles" with a white-filled ellipse). Layers draw in stack order (the default stroke_depth_order is '2D'), so the bubble layer sits above the borders.

Example 2: Handwriting reveal with the Build modifier

User request: "Animate the letters HI being written stroke by stroke"

import bpy

# add_stroke() from step 3 must be defined above this point
gp_data = bpy.data.grease_pencils.new("Handwriting")
gp_obj = bpy.data.objects.new("Handwriting", gp_data)
bpy.context.collection.objects.link(gp_obj)

ink = bpy.data.materials.new("GP_Ink")
bpy.data.materials.create_gpencil_data(ink)
ink.grease_pencil.color = (0.05, 0.05, 0.15, 1)
gp_data.materials.append(ink)

drawing = gp_data.layers.new("Letters").frames.new(1).drawing
add_stroke(drawing, [(0, 0, 0), (0, 2, 0)], radius=0.05)                    # H left bar
add_stroke(drawing, [(0, 1, 0), (1, 1, 0)], radius=0.05)                    # H crossbar
add_stroke(drawing, [(1, 2, 0), (1, 0, 0)], radius=0.05)                    # H right bar
add_stroke(drawing, [(2.5, 2, 0), (2.5, 0, 0)], radius=0.05)                # I

build = gp_obj.modifiers.new("Build", 'GREASE_PENCIL_BUILD')
build.mode = 'SEQUENTIAL'
build.time_mode = 'FRAMES'
build.length = 60

scene = bpy.context.scene
scene.frame_start, scene.frame_end = 1, 60
bpy.ops.wm.save_as_mainfile(filepath="/tmp/handwriting.blend")

Result: scrubbing frames 1-60 shows the four strokes appearing one after another.

Guidelines

  • Use bpy.data.grease_pencils.new() for data-level creation; bpy.ops.object.grease_pencil_add() is for quick objects and needs a valid context.
  • Assign at least one Grease Pencil material before rendering: strokes without a material slot do not show the colors you intended.
  • Stroke thickness is radius per point (scene units), not a pixel line_width; there is no pressure or strength any more (use radius and opacity).
  • Never keep references to drawing.strokes[n] across add_strokes, remove_strokes or resize_strokes; re-fetch or use attributes.
  • Layer names are layer.name; blend modes are REGULAR, HARDLIGHT, ADD, SUBTRACT, MULTIPLY, DIVIDE (OVERLAY is gone).
  • layer.frames.new() fails if the frame number is taken; use layer.get_frame_at() or layer.frames.remove() first.
  • Never hardcode enum names from memory: read them, for example [i.identifier for i in bpy.types.Modifier.bl_rna.properties["type"].enum_items].
  • Build modifier is the cheapest way to animate stroke reveal without per-frame scripting.
  • Scripts here were checked against the API reference, not executed in Blender: run them once in blender --background --python script.py and watch the console before relying on them.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Scripts and configures production rendering in Autodesk 3ds Max with the V-Ray and Corona renderers: output size and files, render elements, denoising, light mix, batch and command-line rendering, and network rendering. Use when a user asks to set up a production render, render several cameras in one batch, render from the command line or on a render farm, add render passes for compositing, or cut render time for archviz and product shots.

中文简介正在准备中。当前显示原文说明。

TerminalSkills/skills1772026年10月22日 更新

Covers scripting Autodesk 3ds Max, the 3D modeling and rendering application, with MAXScript and Python (pymxs): scene manipulation, object creation, material assignment, camera and light setup, batch operations, and file I/O. Use when tasks involve automating repetitive 3ds Max workflows, batch processing scenes, running scripts headless with 3dsmaxbatch, creating custom tools, or scripting scene setup for archviz, product visualization, or VFX.

中文简介正在准备中。当前显示原文说明。

TerminalSkills/skills1772026年10月22日 更新

3proxy

免费

3proxy is a small open-source proxy server that runs HTTP/HTTPS, SOCKS4/5, SNI and TCP/UDP port-mapping proxies from one config file. Use when a user asks to set up an HTTP or SOCKS5 proxy, add proxy users and passwords, write 3proxy access rules, chain or rotate upstream (parent) proxies, limit bandwidth, connections or monthly traffic per user, run 3proxy in Docker, or fix a 3proxy.cfg that will not start.

中文简介正在准备中。当前显示原文说明。

TerminalSkills/skills1772026年10月22日 更新

Builds Agent2Agent (A2A) servers and clients, the open protocol (originally from Google, now under the Linux Foundation) that lets AI agents from different frameworks call each other. Use when the user wants to create an A2A-compliant agent, build an Agent Card, implement task management, connect agents across frameworks, set up agent discovery, handle streaming responses, implement push notifications, or orchestrate multi-agent workflows. Trigger words: a2a, agent to agent, agent2agent, a2a protocol, a2a server, a2a client, agent card, agent interoperability, agent collaboration, multi-agent, agent discovery, a2a sdk, a2a task.

中文简介正在准备中。当前显示原文说明。

TerminalSkills/skills1772026年10月22日 更新

Plans a controlled experiment (A/B test) so its result can be trusted: writes the hypothesis, picks one primary metric and the guardrails, computes sample size and run time, specifies how visitors are assigned and when exposure is logged, and reads out the result with a confidence interval. Use when someone says "set up an A/B test", "split test this page", "how many visitors do I need", "how long should the experiment run", "is this result significant", "can I stop the test early", or wants to test a headline, price, layout or onboarding change against the current version.

中文简介正在准备中。当前显示原文说明。

TerminalSkills/skills1772026年10月22日 更新

ably

免费

Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection. Use when a user asks to "add realtime updates", "push live notifications to the browser", "show who is online", "add a chat room with typing indicators", "publish from a serverless function", or "authenticate Ably clients without exposing the API key". Covers the ably 2.x JavaScript SDK (Realtime and REST), JWT token authentication, presence, history and rewind, batch publishing, and the @ably/chat 1.x SDK.

中文简介正在准备中。当前显示原文说明。

TerminalSkills/skills1772026年10月22日 更新

查看 TerminalSkills 的全部技能

报告此技能的问题