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


import bpy
import random
import math

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

def make_mat(color, rough=0.8):
    m = bpy.data.materials.new("Material")
    m.use_nodes = True
    b = m.node_tree.nodes.get("Principled BSDF")
    if b:
        b.inputs['Base Color'].default_value = color
        b.inputs['Roughness'].default_value = rough
    return m

m_water = make_mat((0.05, 0.25, 0.6, 1.0), 0.4)
m_hull = make_mat((0.35, 0.18, 0.08, 1.0), 0.9)
m_deck = make_mat((0.5, 0.3, 0.15, 1.0), 0.9)
m_sail = make_mat((0.9, 0.9, 0.85, 1.0), 0.9)
m_poop = make_mat((0.16, 0.07, 0.02, 1.0), 0.12)

bpy.ops.mesh.primitive_plane_add(size=60, location=(0, 0, 0))
bpy.context.active_object.data.materials.append(m_water)

bpy.ops.mesh.primitive_cube_add(size=1, location=(0, -3, 0.5))
ship = bpy.context.active_object
ship.scale = (2.6, 5.5, 1.0)
bpy.ops.object.transform_apply(scale=True)
ship.data.materials.append(m_hull)

bpy.ops.mesh.primitive_cube_add(size=1, location=(0, -3, 1.05))
deck = bpy.context.active_object
deck.scale = (2.4, 5.2, 0.1)
bpy.ops.object.transform_apply(scale=True)
deck.data.materials.append(m_deck)
deck.parent = ship
deck.matrix_parent_inverse = ship.matrix_world.inverted()

bpy.ops.mesh.primitive_cube_add(size=1, location=(0, -4.8, 1.5))
cabin = bpy.context.active_object
cabin.scale = (2.2, 1.6, 0.9)
bpy.ops.object.transform_apply(scale=True)
cabin.data.materials.append(m_hull)
cabin.parent = ship
cabin.matrix_parent_inverse = ship.matrix_world.inverted()

bpy.ops.mesh.primitive_cylinder_add(radius=0.15, depth=4.5, location=(0, -2.5, 3.2))
mast = bpy.context.active_object
mast.data.materials.append(m_hull)
mast.parent = ship
mast.matrix_parent_inverse = ship.matrix_world.inverted()

bpy.ops.mesh.primitive_cube_add(size=1, location=(0, -2.3, 3.5))
sail = bpy.context.active_object
sail.scale = (2.8, 0.15, 2.2)
bpy.ops.object.transform_apply(scale=True)
sail.data.materials.append(m_sail)
sail.parent = ship
sail.matrix_parent_inverse = ship.matrix_world.inverted()

random.seed(15)
for _ in range(14):
    px = random.uniform(-0.9, 0.9)
    py = random.uniform(-3.8, -0.8)
    
    for layer in range(4):
        r = 0.16 - layer * 0.032
        z_off = 1.12 + layer * 0.075
        ox = math.sin(layer * 1.8) * 0.03
        oy = math.cos(layer * 1.8) * 0.03
        
        bpy.ops.mesh.primitive_uv_sphere_add(segments=16, ring_count=12, radius=r, location=(px + ox, py + oy, z_off))
        p_part = bpy.context.active_object
        p_part.scale = (1.0, 1.0, 0.65)
        bpy.ops.object.transform_apply(scale=True)
        bpy.ops.object.shade_smooth()
        p_part.data.materials.append(m_poop)
        p_part.parent = ship
        p_part.matrix_parent_inverse = ship.matrix_world.inverted()

bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = 120

ship.location = (0, -3, 0.4)
ship.rotation_euler = (0.07, -0.09, 0.0)
ship.keyframe_insert(data_path="location", frame=1)
ship.keyframe_insert(data_path="rotation_euler", frame=1)

ship.location = (0, 3, 0.65)
ship.rotation_euler = (-0.07, 0.09, 0.0)
ship.keyframe_insert(data_path="location", frame=60)
ship.keyframe_insert(data_path="rotation_euler", frame=60)

ship.location = (0, -3, 0.4)
ship.rotation_euler = (0.07, -0.09, 0.0)
ship.keyframe_insert(data_path="location", frame=120)
ship.keyframe_insert(data_path="rotation_euler", frame=120)

bpy.ops.object.light_add(type='SUN', location=(5, -5, 10), rotation=(0.6, 0.2, 0.5))
bpy.context.active_object.data.energy = 2.5

bpy.ops.object.camera_add(location=(9, -9, 6), rotation=(math.radians(60), 0, math.radians(45)))
bpy.context.scene.camera = bpy.context.active_object

bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.update()