Загрузка данных


import bpy import math import random from mathutils import Vector
==========================================
SNOWMAN DELUXE — Blender Python
==========================================
random.seed(42)
Очистка сцены
bpy.ops.object.select_all(action='SELECT') bpy.ops.object.delete(use_global=False)
for datablocks in ( bpy.data.materials, bpy.data.curves, bpy.data.cameras, bpy.data.lights, ): # Не удаляем данные вручную: Blender очистит ненужное автоматически pass
==========================================
МАТЕРИАЛЫ
==========================================
def make_material(name, color, roughness=0.7, metallic=0.0): mat = bpy.data.materials.new(name) mat.diffuse_color = (*color, 1) mat.use_nodes = True
bsdf = mat.node_tree.nodes.get("Principled BSDF")
bsdf.inputs["Base Color"].default_value = (*color, 1)
bsdf.inputs["Roughness"].default_value = roughness
bsdf.inputs["Metallic"].default_value = metallic

return mat
snow = make_material("Fresh Powder Snow", (0.82, 0.92, 1.0), 0.82) hat_mat = make_material("Midnight Black Hat", (0.025, 0.035, 0.06), 0.32) hat_band = make_material("Ruby Red Hat Band", (0.65, 0.025, 0.055), 0.38) carrot = make_material("Orange Carrot", (1.0, 0.22, 0.025), 0.55) coal = make_material("Black Coal", (0.025, 0.03, 0.04), 0.35) scarf_mat = make_material("Festive Crimson Scarf", (0.65, 0.015, 0.055), 0.65) gold = make_material("Golden Decoration", (1.0, 0.58, 0.08), 0.28, 0.35) wood = make_material("Warm Brown Branches", (0.20, 0.075, 0.025), 0.8) green = make_material("Holly Green", (0.025, 0.22, 0.055), 0.65) berry = make_material("Red Holly Berries", (0.8, 0.015, 0.035), 0.28) ground_mat = make_material("Blue Winter Ground", (0.42, 0.65, 0.82), 0.9)
==========================================
ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
==========================================
def smooth(obj): if obj.type == 'MESH': for polygon in obj.data.polygons: polygon.use_smooth = True return obj
def add_uv_sphere(name, location, scale, material, segments=32, rings=20): bpy.ops.mesh.primitive_uv_sphere_add( segments=segments, ring_count=rings, location=location ) obj = bpy.context.object obj.name = name obj.scale = scale obj.data.materials.append(material) smooth(obj) return obj
def add_cylinder(name, location, radius, depth, material, vertices=48): bpy.ops.mesh.primitive_cylinder_add( vertices=vertices, radius=radius, depth=depth, location=location ) obj = bpy.context.object obj.name = name obj.data.materials.append(material) bevel = obj.modifiers.new("Soft Rounded Edges", 'BEVEL') bevel.width = 0.06 bevel.segments = 3 obj.modifiers.new("Weighted Corner Normals", 'WEIGHTED_NORMAL') return obj
def add_cone_between(name, start, end, radius, material, vertices=12): start = Vector(start) end = Vector(end) direction = end - start
midpoint = (start + end) / 2

bpy.ops.mesh.primitive_cone_add(
    vertices=vertices,
    radius1=radius,
    radius2=0.012,
    depth=direction.length,
    location=midpoint
)

obj = bpy.context.object
obj.name = name
obj.rotation_mode = 'QUATERNION'
obj.rotation_quaternion = direction.to_track_quat('Z', 'Y')
obj.data.materials.append(material)
smooth(obj)
return obj
def add_torus(name, location, major_radius, minor_radius, material): bpy.ops.mesh.primitive_torus_add( major_segments=48, minor_segments=12, location=location, major_radius=major_radius, minor_radius=minor_radius ) obj = bpy.context.object obj.name = name obj.data.materials.append(material) smooth(obj) return obj
==========================================
СНЕГОВИК: ТРИ СНЕЖНЫХ ШАРА
==========================================
Нижний шар
add_uv_sphere( "Snowman Body - Bottom", (0, 0, 1.05), (1.05, 0.88, 1.05), snow, 48, 32 )
Средний шар
add_uv_sphere( "Snowman Body - Middle", (0, 0, 2.45), (0.79, 0.69, 0.78), snow, 48, 32 )
Голова
add_uv_sphere( "Snowman Head", (0, 0, 3.52), (0.59, 0.54, 0.58), snow, 48, 32 )
==========================================
ГЛАЗА
==========================================
for side in (-1, 1): add_uv_sphere( "Coal Eye", (side * 0.205, -0.495, 3.63), (0.075, 0.055, 0.09), coal )
# Маленькие блики
add_uv_sphere(
    "Eye Sparkle",
    (side * 0.205 - 0.018, -0.545, 3.66),
    (0.018, 0.012, 0.021),
    snow,
    16,
    12
)
==========================================
МОРКОВНЫЙ НОС
==========================================
nose_start = (0, -0.48, 3.49) nose_end = (0, -0.94, 3.43)
add_cone_between( "Long Carrot Nose", nose_start, nose_end, 0.115, carrot, 32 )
==========================================
УГОЛЬНАЯ УЛЫБКА
==========================================
for i in range(7): x = (i - 3) * 0.105 z = 3.30 - 0.09 * (1 - (x / 0.32) ** 2)
add_uv_sphere(
    "Smile Coal",
    (x, -0.505, z),
    (0.038, 0.03, 0.04),
    coal,
    20,
    12
)
==========================================
ШЛЯПА-ЦИЛИНДР
==========================================
Поля шляпы
add_cylinder( "Top Hat Brim", (0, 0, 4.08), 0.72, 0.12, hat_mat )
Основная часть
add_cylinder( "Top Hat Crown", (0, 0, 4.43), 0.47, 0.65, hat_mat )
Красная лента
add_torus( "Red Hat Ribbon", (0, 0, 4.20), 0.465, 0.045, hat_band )
Золотая брошь
add_uv_sphere( "Golden Hat Pin", (0.34, -0.335, 4.20), (0.065, 0.035, 0.065), gold )
==========================================
ШАРФ
==========================================
Основная полоса шарфа вокруг шеи
add_torus( "Thick Winter Scarf", (0, 0, 2.99), 0.59, 0.13, scarf_mat )
Свисающий конец шарфа
tail = add_uv_sphere( "Scarf Hanging Tail", (0.43, -0.48, 2.65), (0.17, 0.09, 0.48), scarf_mat ) tail.rotation_euler[1] = -0.18
Полоски на шарфе
for z in (2.48, 2.61, 2.74, 2.87): add_uv_sphere( "Scarf Golden Stripe", (0.43, -0.565, z), (0.172, 0.018, 0.025), gold, 20, 12 )
Бахрома
for i in range(5): x = 0.31 + i * 0.06 add_cone_between( "Scarf Fringe", (x, -0.48, 2.28), (x + random.uniform(-0.025, 0.025), -0.48, 2.18), 0.025, scarf_mat, 8 )
==========================================
ПУГОВИЦЫ
==========================================
for z, size in ((2.70, 0.105), (2.35, 0.09), (1.96, 0.085)): add_uv_sphere( "Coal Body Button", (0, -0.695 if z > 2.5 else -0.75, z), (size, 0.05, size), coal )
==========================================
РУКИ И ПАЛЬЦЫ ИЗ ВЕТОК
==========================================
Левая и правая руки
branches = [ ((-0.64, 0, 2.72), (-1.25, 0, 3.00)), ((-1.25, 0, 3.00), (-1.52, 0, 3.28)), ((-1.25, 0, 3.00), (-1.58, 0, 2.98)), ((0.64, 0, 2.72), (1.25, 0, 3.00)), ((1.25, 0, 3.00), (1.53, 0, 3.25)), ((1.25, 0, 3.00), (1.59, 0, 2.96)), ]
for idx, (start, end) in enumerate(branches): add_cone_between( f"Twig Arm {idx + 1}", start, end, 0.075 if idx in (0, 3) else 0.045, wood, 12 )
==========================================
ЛИСТЬЯ И ЯГОДЫ ОСТРОЛИСТА
==========================================
Декоративная веточка на шляпе
for x, z, angle in [ (-0.18, 4.22, -0.5), (-0.32, 4.28, 0.4), (-0.26, 4.12, -0.2), ]: leaf = add_uv_sphere( "Holly Leaf", (x, -0.43, z), (0.15, 0.035, 0.07), green ) leaf.rotation_euler[1] = angle
for x, z in [(-0.28, 4.20), (-0.38, 4.17), (-0.33, 4.29)]: add_uv_sphere( "Holly Berry", (x, -0.48, z), (0.045, 0.035, 0.045), berry, 20, 12 )
==========================================
СНЕЖНЫЕ КРИСТАЛЛЫ НА ТЕЛЕ
==========================================
for i in range(35): z = random.uniform(0.55, 3.95)
if z < 1.9:
    radius = random.uniform(0.7, 1.0)
elif z < 3.0:
    radius = random.uniform(0.5, 0.72)
else:
    radius = random.uniform(0.38, 0.54)

angle = random.uniform(-math.pi, math.pi)

x = radius * math.sin(angle)
y = -radius * math.cos(angle)

# Не размещаем кристаллы слишком далеко от поверхности
if y < -0.12:
    crystal = add_uv_sphere(
        "Tiny Snow Crystal",
        (x, y, z),
        (0.025, 0.018, 0.025),
        snow,
        12,
        8
    )
==========================================
СНЕЖНАЯ ПЛОЩАДКА
==========================================
bpy.ops.mesh.primitive_plane_add( size=200, location=(0, 0, -0.08) ) ground = bpy.context.object ground.name = "Endless Snow Ground" ground.data.materials.append(ground_mat)
==========================================
ПАДАЮЩИЕ СНЕЖИНКИ
==========================================
for i in range(100): x = random.uniform(-5, 5) y = random.uniform(-2, 3) z = random.uniform(0.2, 7)
size = random.uniform(0.018, 0.045)

add_uv_sphere(
    "Floating Snowflake",
    (x, y, z),
    (size, size, size),
    snow,
    12,
    8
)
==========================================
КАМЕРА
==========================================
bpy.ops.object.camera_add( location=(6.4, -11.5, 5.4) )
camera = bpy.context.object camera.name = "Snowman Portrait Camera"
target = Vector((0, 0, 2.35)) direction = target - camera.location
camera.rotation_euler = direction.to_track_quat('-Z', 'Y').to_euler() camera.data.lens = 58 bpy.context.scene.camera = camera
==========================================
ОСВЕЩЕНИЕ
==========================================
def add_area_light(name, location, energy, color, size): bpy.ops.object.light_add( type='AREA', location=location )
light = bpy.context.object
light.name = name
light.data.energy = energy
light.data.color = color
light.data.shape = 'DISK'
light.data.size = size

direction = Vector((0, 0, 2.3)) - light.location
light.rotation_euler = direction.to_track_quat('-Z', 'Y').to_euler()

return light
add_area_light( "Warm Key Light", (4, -6, 8), 1000, (1.0, 0.82, 0.66), 5 )
add_area_light( "Cold Blue Fill Light", (-5, -3, 5), 850, (0.48, 0.72, 1.0), 4 )
add_area_light( "Winter Rim Light", (1, 4, 6), 1300, (0.55, 0.8, 1.0), 3 )
==========================================
НАСТРОЙКИ РЕНДЕРА
==========================================
scene = bpy.context.scene
scene.render.engine = 'CYCLES' scene.cycles.samples = 48
Denoising — подавление шума
scene.cycles.use_denoising = True
scene.render.resolution_x = 1200 scene.render.resolution_y = 1200 scene.render.resolution_percentage = 100
scene.render.image_settings.file_format = 'PNG' scene.render.filepath = "//snowman_render.png"
scene.world.color = (0.16, 0.22, 0.32)
Цветовой стиль
scene.view_settings.view_transform = 'AgX'
Настройка камеры
camera.data.dof.use_dof = True camera.data.dof.focus_object = bpy.data.objects.get("Snowman Head") camera.data.dof.aperture_fstop = 8
Выбираем снеговика
bpy.ops.object.select_all(action='DESELECT')
head = bpy.data.objects.get("Snowman Head") if head: head.select_set(True) bpy.context.view_layer.objects.active = head
print("====================================") print("SNOWMAN DELUXE CREATED SUCCESSFULLY!") print("Press F12 to render your snowman.") print("Save your project using File > Save As.") print("====================================")