CULTIVA IA
blender-grease-pencil-python
bpy · Blender 3.0+
Video · avanzado

Blender Grease Pencil con Python

Crea dibujos 2D y animaciones en Blender usando scripts Python con la API bpy. Trazos vectoriales, capas, materiales y modificadores 100% programáticos.

Vista previa — geometría generada por script
Panel de cómic (Example 1)
Animación círculo (frame 12/24)
Logo CULTIVA IA — Handwriting
Flujo de trabajo
01
GP Object
bpy.data.grease_pencils.new() + object link
02
Layers & Frames
layers.new() → frames.new(frame_number=N)
03
Strokes
strokes.new() → points.add(N) → .co/.pressure
04
Materials
create_gpencil_data() + .color / .fill_color
05
Modifiers
grease_pencil_modifiers.new() GP_BUILD / GP_SMOOTH
06
Render / Export
bpy.ops.render.render(animation=True)
Snippets principales
1
Crear objeto Grease Pencil
Python / bpy
import bpy

# Crear data block y objeto
gp_data = bpy.data.grease_pencils.new("MiDibujo")
gp_obj  = bpy.data.objects.new("MiDibujo", gp_data)
bpy.context.collection.objects.link(gp_obj)

# O con operador (EMPTY / STROKE / MONKEY)
bpy.ops.object.gpencil_add(type='EMPTY')
gp_obj = bpy.context.active_object
2
Capas y fotogramas
Python / bpy
# Capa de contornos
layer = gp_data.layers.new("Contornos", set_active=True)
layer.blend_mode = 'REGULAR'
layer.opacity    = 1.0

# Keyframe en frame 1
frame = layer.frames.new(frame_number=1)

# Capa secundaria de rellenos
fill_layer = gp_data.layers.new("Rellenos")
fill_frame = fill_layer.frames.new(frame_number=1)
3
Trazar strokes con puntos
Python / bpy
import math

stroke = frame.strokes.new()
stroke.display_mode  = '3DSPACE'
stroke.line_width    = 10
stroke.material_index = 0

num_pts = 32
stroke.points.add(num_pts)

for i in range(num_pts):
    angle = (2 * math.pi * i) / num_pts
    stroke.points[i].co       = (math.cos(angle), math.sin(angle), 0)
    stroke.points[i].pressure = 1.0
    stroke.points[i].strength = 1.0
4
Materiales GP
Python / bpy
# Material sólido con relleno
mat = bpy.data.materials.new("GP_Verde")
bpy.data.materials.create_gpencil_data(mat)

mat.grease_pencil.color       = (0.05, 0.05, 0.05, 1)
mat.grease_pencil.fill_color  = (0.18, 0.80, 0.44, 1)
mat.grease_pencil.show_fill   = True
mat.grease_pencil.show_stroke = True

gp_obj.data.materials.append(mat)
Ejemplo completo — Logo animado CULTIVA IA
Script completo: logo CULTIVA IA con reveal animado (60 frames)
Python / bpy
import bpy, math

# 1. Limpiar escena
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# 2. Crear objeto GP
gp_data = bpy.data.grease_pencils.new("LogoCultiva")
gp_obj  = bpy.data.objects.new("LogoCultiva", gp_data)
bpy.context.collection.objects.link(gp_obj)
bpy.context.view_layer.objects.active = gp_obj

# 3. Materiales: negro (trazo) y verde (acento)
mat_black = bpy.data.materials.new("GP_Negro")
bpy.data.materials.create_gpencil_data(mat_black)
mat_black.grease_pencil.color       = (0.05, 0.05, 0.05, 1.0)
mat_black.grease_pencil.show_fill   = False
mat_black.grease_pencil.show_stroke = True

mat_green = bpy.data.materials.new("GP_Verde")
bpy.data.materials.create_gpencil_data(mat_green)
mat_green.grease_pencil.color       = (0.18, 0.80, 0.44, 1.0)
mat_green.grease_pencil.fill_color  = (0.18, 0.80, 0.44, 0.2)
mat_green.grease_pencil.show_fill   = True
mat_green.grease_pencil.show_stroke = True

gp_data.materials.append(mat_black)   # index 0
gp_data.materials.append(mat_green)   # index 1

# 4. Capa principal — trazos de texto
layer = gp_data.layers.new("Letras", set_active=True)
frame = layer.frames.new(frame_number=1)

# Trazos simplificados de "CULTIVA IA" (coordenadas normalizadas)
letra_paths = [
    [(-4.0,  1.0, 0), (-4.5,  1.0, 0), (-4.5, -1.0, 0), (-4.0, -1.0, 0)],  # C
    [(-3.5,  1.0, 0), (-3.5, -1.0, 0), (-3.2, -1.0, 0)],  # U
    [(-2.8,  1.0, 0), (-2.8, -1.0, 0)],  # L
    [(-2.4,  1.0, 0), (-2.0,  1.0, 0), (-2.2,  0.0, 0), (-2.0, -1.0, 0), (-2.4, -1.0, 0)],  # T
    [(-1.6,  1.0, 0), (-1.2, -1.0, 0), (-0.8,  1.0, 0)],  # I (chevron)
    [(-0.4,  1.0, 0), ( 0.0, -1.0, 0), ( 0.4,  1.0, 0)],  # V
    [( 0.7,  1.0, 0), ( 0.7, -1.0, 0), ( 1.1, -0.5, 0), ( 1.1,  1.0, 0)],  # A
    # Separador + IA
    [( 1.7,  1.0, 0), ( 1.7, -1.0, 0)],  # I
    [( 2.1,  1.0, 0), ( 2.5, -1.0, 0), ( 2.9,  1.0, 0), ( 2.2,  0.0, 0), ( 2.8,  0.0, 0)],  # A
]

for path in letra_paths:
    st = frame.strokes.new()
    st.display_mode   = '3DSPACE'
    st.line_width     = 12
    st.material_index = 0
    st.points.add(len(path))
    for i, co in enumerate(path):
        st.points[i].co       = co
        st.points[i].pressure = 1.0
        st.points[i].strength = 1.0

# 5. Capa acento verde — subrayado
accent_layer = gp_data.layers.new("Acento")
af = accent_layer.frames.new(frame_number=1)
ul = af.strokes.new()
ul.display_mode   = '3DSPACE'
ul.line_width     = 6
ul.material_index = 1
ul.points.add(2)
ul.points[0].co = (-4.5, -1.4, 0)
ul.points[1].co = ( 2.9, -1.4, 0)
ul.points[0].pressure = ul.points[1].pressure = 1.0

# 6. Modificador Build — reveal secuencial
build = gp_obj.grease_pencil_modifiers.new("Reveal", 'GP_BUILD')
build.mode        = 'SEQUENTIAL'
build.start_frame = 1
build.length      = 60

# 7. Modificador Smooth para aspecto artesanal
smooth = gp_obj.grease_pencil_modifiers.new("Suavizado", 'GP_SMOOTH')
smooth.factor = 0.3
smooth.step   = 2

# 8. Rango de animación
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end   = 60

bpy.ops.wm.save_as_mainfile(filepath="/tmp/cultiva_logo_gp.blend")
print("Logo CULTIVA IA guardado en /tmp/cultiva_logo_gp.blend")
Constante Nombre Uso típico Props clave
GP_BUILD Build Reveal animado de trazos mode start_frame length
GP_THICK Thickness Variar grosor de trazo thickness_factor
GP_SMOOTH Smooth Suavizar puntos (look artesanal) factor step
GP_NOISE Noise Efecto trazo a mano factor
GP_TINT Tint Virar color de capa color factor
GP_SUBDIV Subdivide Curvas más suaves level
GP_ARRAY Array Repetir trazos (patrones) count offset