Blender AI Wiki / English Поиск

P07: INSTANCING & ARRAYS

Efficient duplication and distribution of objects using Array modifier, Collection instances, and Geometry Nodes

📝 Промпты ⭐⭐ 7 блоков кода обновлено 2026-10-01

ID: P07 | Cluster: Geometry Basics | Difficulty: ⭐⭐ | Tags: #instances #array #collection #geometry-nodes #procedural


🎯 GOAL

Efficient duplication and distribution of objects using Array modifier, Collection instances, and Geometry Nodes


📝 PROMPT (RUS)

Создай массив/распределение "[OBJECT_NAME]":
Метод: ARRAY_MODIFIER / COLLECTION_INSTANCE / GEOMETRY_NODES
Параметры: count, offset, randomize, scale, rotation

📝 PROMPT (ENG)

Create array/distribution of "[OBJECT_NAME]":
Method: ARRAY_MODIFIER / COLLECTION_INSTANCE / GEOMETRY_NODES
Parameters: count, offset, randomize, scale, rotation

🔧 MCP: execute_blender_code

ARRAY MODIFIER (Простой линейный)

import bpy

obj = bpy.data.objects.get("Source_Obj")
if not obj:
    raise ValueError("Object not found")

# Array Modifier
array = obj.modifiers.new("Array_Linear", 'ARRAY')
array.count = 10
array.use_relative_offset = True
array.relative_offset_displace = (2.0, 0, 0)  # 2м между экземплярами

# Array по кривой
curve = bpy.data.curves.new("Path", 'CURVE')
curve.dimensions = '3D'
spline = curve.splines.new('BEZIER')
spline.bezier_points.add(3)
# ... настроить точки кривой

curve_obj = bpy.data.objects.new("Path", curve)
bpy.context.collection.objects.link(curve_obj)

array2 = obj.modifiers.new("Array_Curve", 'ARRAY')
array2.fit_type = 'FIT_CURVE'
array2.curve = curve_obj
array2.use_relative_offset = True
array2.relative_offset_displace = (0, 0, 1.0)

COLLECTION INSTANCES (Лёгкие, для сцены)

import bpy

# Создать коллекцию с вариациями
col = bpy.data.collections.new("Props_Variants")
for i in range(5):
    var = bpy.data.objects.get(f"Prop_Var_{i}")
    if var:
        col.objects.link(var)

# Инстанс коллекции
instance = bpy.data.objects.new("Instancer", None)
instance.instance_type = 'COLLECTION'
instance.instance_collection = col
bpy.context.collection.objects.link(instance)

# Настроить распределение (Geometry Nodes лучше)

GEOMETRY NODES (Полный контроль)

import bpy

# Создать GN дерево
gn = bpy.data.node_groups.new("Scatter_Props", 'GeometryNodeTree')
nodes = gn.nodes
links = gn.links
nodes.clear()

# Input/Output
inp = nodes.new('NodeGroupInput')
out = nodes.new('NodeGroupOutput')
gn.interface.new_socket(name="Count", in_out='INPUT', socket_type='NodeSocketInt')
gn.interface.new_socket(name="Geometry", in_out='OUTPUT', socket_type='NodeSocketGeometry')
gn.interface.new_socket(name="Source", in_out='INPUT', socket_type='NodeSocketObject')

inp.location = (-400, 0)
out.location = (400, 0)

# Nodes
distribute = nodes.new('GeometryNodeDistributePointsOnFaces')
distribute.location = (0, 0)
distribute.distribute_method = 'POISSON'

instance = nodes.new('GeometryNodeInstanceOnPoints')
instance.location = (200, 0)
instance.inputs['Scale'].default_value = (1, 1, 1)

realize = nodes.new('GeometryNodeRealizeInstances')
realize.location = (400, 0)

# Links
links.new(inp.outputs['Source'], distribute.inputs['Mesh'])
links.new(inp.outputs['Count'], distribute.inputs['Density'])
links.new(distribute.outputs['Points'], instance.inputs['Points'])
links.new(inp.outputs['Source'], instance.inputs['Instance'])
links.new(instance.outputs['Instances'], realize.inputs['Geometry'])
links.new(realize.outputs['Geometry'], out.inputs['Geometry'])

# Применить к объекту-эмиттеру
emitter = bpy.data.objects.get("Ground")
mod = emitter.modifiers.new("GN_Scatter", 'NODES')
mod.node_group = gn
mod["Input_1"] = 1000  # Count
mod["Input_2"] = bpy.data.objects.get("Prop_Source")  # Source

📊 СРАВНЕНИЕ МЕТОДОВ

Метод Память Гибкость Анимация Сложность
Array Modifier Низкая Низкая Да ⭐
Collection Instance Очень низкая Средняя Ограничено ⭐⭐
Geometry Nodes Низкая Максимальная Да ⭐⭐⭐

💡 ПРО ТИПЫ

Случайные вариации (GN)

# Random Scale
rand_scale = nodes.new('GeometryNodeRandomValue')
rand_scale.data_type = 'FLOAT_VECTOR'
rand_scale.outputs[0].default_value = (0.8, 0.8, 0.8)
rand_scale.outputs[1].default_value = (1.2, 1.2, 1.2)
links.new(rand_scale.outputs['Value'], instance.inputs['Scale'])

# Random Rotation
rand_rot = nodes.new('GeometryNodeRandomValue')
rand_rot.data_type = 'FLOAT_VECTOR'
rand_rot.outputs[0].default_value = (0, 0, 0)
rand_rot.outputs[1].default_value = (0, 0, 6.28)
links.new(rand_rot.outputs['Value'], instance.inputs['Rotation'])

Weight Paint для плотности

# Vertex Group "Density" на эмиттере
distribute.inputs['Density Attribute'].default_value = "Density"

🔗 СВЯЗИ

Связанные материалы

Подобраны по тегам и категории.