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


import bpy
import math

# --- НАСТРОЙКИ ---
# Укажите здесь пути к вашим картинкам (используйте прямые слэши /)
WOOD_IMAGE_PATH = "C:/path/to/wood_texture.jpg" 
CLOTH_IMAGE_PATH = "C:/path/to/cloth_texture.jpg"

def clear_scene():
    """Очищает сцену от стандартных объектов"""
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete(use_global=False)

def create_material(name, image_path=None):
    """Создает материал с настройками по умолчанию"""
    mat = bpy.data.materials.new(name=name)
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links
    
    # Очищаем стандартные узлы
    for node in nodes:
        nodes.remove(node)
        
    # Создаем основные узлы (как на скриншотах)
    output = nodes.new(type='ShaderNodeOutputMaterial')
    output.location = (600, 0)
    
    bsdf = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf.location = (300, 0)
    links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    
    if image_path:
        # Узел текстуры
        tex_node = nodes.new(type='ShaderNodeTexImage')
        tex_node.location = (0, 0)
        try:
            img = bpy.data.images.load(image_path)
            tex_node.image = img
        except:
            print(f"Не удалось загрузить изображение: {image_path}")
        
        # Узел тектурных координат
        tex_coord = nodes.new(type='ShaderNodeTexCoord')
        tex_coord.location = (-600, 0)
        
        # Узел отображения (Mapping)
        mapping = nodes.new(type='ShaderNodeMapping')
        mapping.location = (-300, 0)
        # Настройки масштаба для дерева (примерно как на скрине)
        if "wood" in name.lower():
            mapping.inputs['Scale'].default_value = (1.0, 1.0, 1.0) 
        
        # Соединяем узлы
        links.new(tex_coord.outputs['UV'], mapping.inputs['Vector'])
        links.new(mapping.outputs['Vector'], tex_node.inputs['Vector'])
        links.new(tex_node.outputs['Color'], bsdf.inputs['Base Color'])
        
        # Настройки шероховатости (по скриншотам)
        if "wood" in name.lower():
            bsdf.inputs['Roughness'].default_value = 0.4
        elif "cloth" in name.lower():
            bsdf.inputs['Roughness'].default_value = 0.8

    return mat

def create_table():
    """Создает ножки и столешницу (упрощенно)"""
    # Столешница
    bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 1))
    table_top = bpy.context.active_object
    table_top.name = "Table_Top"
    table_top.scale = (1.0, 0.6, 0.05) # Делаем плоской
    
    # Ножка 1
    bpy.ops.mesh.primitive_cube_add(size=2, location=(-0.8, -0.4, 0.5))
    leg1 = bpy.context.active_object
    leg1.name = "Leg_1"
    leg1.scale = (0.05, 0.05, 0.5)
    
    # Ножка 2
    bpy.ops.mesh.primitive_cube_add(size=2, location=(0.8, -0.4, 0.5))
    leg2 = bpy.context.active_object
    leg2.name = "Leg_2"
    leg2.scale = (0.05, 0.05, 0.5)
    
    # Ножка 3
    bpy.ops.mesh.primitive_cube_add(size=2, location=(-0.8, 0.4, 0.5))
    leg3 = bpy.context.active_object
    leg3.name = "Leg_3"
    leg3.scale = (0.05, 0.05, 0.5)
    
    # Ножка 4
    bpy.ops.mesh.primitive_cube_add(size=2, location=(0.8, 0.4, 0.5))
    leg4 = bpy.context.active_object
    leg4.name = "Leg_4"
    leg4.scale = (0.05, 0.05, 0.5)
    
    # Объединяем в один объект (Ctrl+J)
    bpy.ops.object.select_all(action='DESELECT')
    table_top.select_set(True)
    leg1.select_set(True)
    leg2.select_set(True)
    leg3.select_set(True)
    leg4.select_set(True)
    bpy.context.view_layer.objects.active = table_top
    bpy.ops.object.join()
    
    return bpy.context.active_object

def create_cloth():
    """Создает плоскость для скатерти и подразделяет её (Шаги 10-12)"""
    bpy.ops.mesh.primitive_plane_add(size=3, location=(0, 0, 1.05))
    cloth = bpy.context.active_object
    cloth.name = "Tablecloth"
    
    # Входим в режим редактирования для подразделения
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='SELECT')
    # Подразделяем несколько раз (Subdivide)
    bpy.ops.mesh.subdivide(number_cuts=20) 
    bpy.ops.object.mode_set(mode='OBJECT')
    
    return cloth

def setup_physics(table, cloth):
    """Настройка физики (Шаги 14-15)"""
    # Физика для скатерти (Ткань)
    bpy.context.view_layer.objects.active = cloth
    bpy.ops.object.modifier_add(type='CLOTH')
    cloth_mod = cloth.modifiers["Cloth"]
    cloth_mod.settings.quality = 10 # Качество симуляции
    
    # Физика для стола (Столкновение)
    bpy.context.view_layer.objects.active = table
    bpy.ops.object.modifier_add(type='COLLISION')
    
    # Слегка приподнимем скатерть, чтобы она не пересекалась со столом в начале
    cloth.location.z += 0.2

# --- ЗАПУСК ---
clear_scene()

# 1. Создаем объекты
table_obj = create_table()
cloth_obj = create_cloth()

# 2. Создаем материалы (Шаги 4-9, 13)
wood_mat = create_material("Wood_Material", WOOD_IMAGE_PATH)
cloth_mat = create_material("Cloth_Material", CLOTH_IMAGE_PATH)

# 3. Назначаем материалы
if table_obj.data.materials:
    table_obj.data.materials[0] = wood_mat
else:
    table_obj.data.materials.append(wood_mat)

if cloth_obj.data.materials:
    cloth_obj.data.materials[0] = cloth_mat
else:
    cloth_obj.data.materials.append(cloth_mat)

# 4. Настраиваем физику (Шаги 14-15)
setup_physics(table_obj, cloth_obj)

# 5. Настройка сцены
bpy.context.scene.render.engine = 'CYCLES' # Или 'BLENDER_EEVEE'
print("Скрипт выполнен! Проверьте папку с картинками, если текстуры не появились.")