Error in user YAML: (<unknown>): found a tab character that violate indentation while scanning a plain scalar at line 3 column 3
---
- oeasy Python 0694
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
- 本教程同步发布在:
- 个人网站: `https://oeasy.org`
- 蓝桥云课: `https://www.lanqiao.cn/courses/3584`
- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial`
- Gitee: `https://gitee.com/overmind1980/oeasypython`
---- 上次将 静态渲染 一条龙
- 建模
- 材质
- 灯光
- 渲染
- 封装
- 用 blender 还能做点啥
好玩的?🤔
import bpy
import math
import colorsys
# 删除默认的场景内容
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
# 创建花的中心
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.5, location=(0, 0, 0))
center = bpy.context.object
center.name = "flower_center"
# 创建一个黄色的材料(花心)- 使用 Principled BSDF
yellow_material = bpy.data.materials.new(name="Yellow")
yellow_material.use_nodes = True
# 获取 Principled BSDF 节点并设置 Base Color
principled_node = yellow_material.node_tree.nodes.get('Principled BSDF')
if principled_node:
principled_node.inputs['Base Color'].default_value = (1, 1, 0, 1) # RGBA: 黄色
center.data.materials.append(yellow_material)
# 创建花瓣并摆放成花朵形状
num_petals = 8
angle_step = 360 / num_petals
petal_radius = 0.3
for i in range(num_petals):
angle = math.radians(i * angle_step)
x = math.cos(angle) * 1.5
y = math.sin(angle) * 1.5
# 创建一个花瓣
bpy.ops.mesh.primitive_uv_sphere_add(radius=petal_radius, location=(x, y, 0))
petal = bpy.context.object
petal.name = f"petal_{i+1}"
# 设定花瓣形状
petal.scale[0] = 4
petal.scale[1] = 1
petal.scale[2] = 0.2
# 将花瓣旋转到合适的位置
petal.rotation_euler = (3, 0, angle)
# 设置花瓣的父对象为花的中心
petal.parent = center
# 创建粉色渐变材质
hue = 0.95 # 粉色系的色相(H值)
saturation = 0.6 + (i / num_petals) * 0.4 # 从0.6到1的渐变
value = 1 # 保持最大亮度
r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
petal_material = bpy.data.materials.new(name=f"Petal_{i+1}")
petal_material.use_nodes = True
# 设置花瓣材质的 Base Color
petal_principled = petal_material.node_tree.nodes.get('Principled BSDF')
if petal_principled:
petal_principled.inputs['Base Color'].default_value = (r, g, b, 1) # RGBA
# 将材质应用到花瓣上
petal.data.materials.append(petal_material)
# 创建聚光灯并调整其属性
bpy.ops.object.light_add(type='SPOT', radius=1.0, location=(0, 0, 3))
spot_light = bpy.context.object
spot_light.name = "SpotLight"
spot_light.data.energy = 200.0 # 设置光源强度
spot_light.data.spot_size = math.radians(60) # 聚光灯的角度
spot_light.data.spot_blend = 0.2 # 聚光灯的软化程度
spot_light.rotation_euler = (math.radians(0), 0, 0) # 调整光源角度
# 创建摄像机并移动到远一点的位置
bpy.ops.object.camera_add(location=(4, -6, 3))
camera = bpy.context.object
camera.name = "Camera"
camera.rotation_euler = (math.radians(60), 0, math.radians(45))
# 设置渲染设置
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.device = 'GPU' # 如果有GPU可用的话
bpy.context.scene.render.resolution_x = 1920
bpy.context.scene.render.resolution_y = 1080
bpy.context.scene.render.filepath = '/path/to/save/render.png'
# 设置场景的摄像机
bpy.context.scene.camera = camera
# 渲染图像
# bpy.ops.render.render(write_still=True)- 盆栽
import bpy
import math
# 删除所有对象
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
# 创建基础圆柱体
bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=1, depth=1.5, location=(0, 0, 0))
pot = bpy.context.active_object
pot.name = "Flower_Pot"
# 编辑模式下挤出和缩放以创建花盆形状
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.transform.translate(value=(0, 0, 0.8)) # 移动到正确的位置
bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value":(0, 0, 0.7)}) # 向下挤出
bpy.ops.transform.resize(value=(1.2, 1.2, 0.3)) # 缩小底部
bpy.ops.object.mode_set(mode='OBJECT')
# 创建花盆的颜色材质
pot_material = bpy.data.materials.new(name="Pot_Material")
pot_material.diffuse_color = (0.6, 0.3, 0.1, 1)
pot.data.materials.append(pot_material)
# 创建一个花茎(圆柱体)
bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=0.2, depth=2, location=(0, 0, 2.5))
stem = bpy.context.active_object
stem.name = "Flower_stem"
#color
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0.8, 0.2, 0.1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
# 创建圆柱体
bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=0.1, depth=0.7, location=(0, -0.2, 2.5))
cylinder = bpy.context.active_object
cylinder.name = "Slanted_cylinder"
#color
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0.6, 0.3, 0.2, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
# 设置圆柱体的旋转角度(以弧度为单位)
# 欧拉角使用顺序为 X-Y-Z (pitch-roll-yaw)
rotation_angle_x = math.radians(45) # 在X轴方向上旋转45度
# 设置旋转角度
cylinder.rotation_euler = (rotation_angle_x, 0, 0)
# 创建圆柱体2
bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=0.1, depth=0.7, location=(0, 0.4, 2.8))
cylinder = bpy.context.active_object
cylinder.name = "Slanted_cylinder2"
#color
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0.6, 0.3, 0.2, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
# 设置圆柱体的旋转角度(以弧度为单位)
# 欧拉角使用顺序为 X-Y-Z (pitch-roll-yaw)
rotation_angle_x = math.radians(-45) # 在X轴方向上旋转45度
# 设置旋转角度
cylinder.rotation_euler = (rotation_angle_x, 0, 0)
# 添加简单变形修改器以弯曲花茎
bend_modifier = stem.modifiers.new(name="SimpleDeform", type='SIMPLE_DEFORM')
bend_modifier.deform_method = 'BEND'
bend_modifier.angle = math.radians(20) # 你可以根据需要调整弯曲角度
bend_modifier.origin = bpy.context.object
# 更新视图以应用修改
bpy.context.view_layer.update()
# 创建球体
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.7, location=(0, 0.1, 3.8))
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0.2, 1, 0.2, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
# 创建球体
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.6, location=(0, 0.1, 4.3))
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0.5, 1, 0.2, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
# 创建球体
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.5, location=(0, 0.1, 4.8))
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0, 1, 0.5, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
# 创建球体
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.38, location=(0, -0.5, 2.8))
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0, 1, 0.7, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
# 创建球体
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.26, location=(0, 0.7, 3.1))
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0.2, 1.2, 0.2, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
# 创建球体
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.2, location=(0, 0.82, 3.2))
mat = bpy.data.materials.new('mat_tree')
mat.use_nodes = True
color = (0.2, 1, 0.2, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
#camera
camera = bpy.data.cameras.new('MyCamera')
camera_obj = bpy.data.objects.new('CameraObj', camera)
bpy.context.scene.collection.objects.link(camera_obj)
camera.lens = 50 # Focal length in millimeters
camera.sensor_width = 36 # Sensor width in millimeters
camera.sensor_height = 24 # Sensor height in millimeters
camera_obj.location = (10.787, 0.34901, 10.312) # X, Y, Z coordinates
camera_obj.rotation_euler = (53.2*0.0174444444,0*0.0174444444,90*0.0174444444)
#渲染?
bpy.context.scene.camera = camera_obj
bpy.ops.object.light_add(type='SPOT', radius=1)
bpy.context.object.data.energy = 1000
bpy.context.object.location = (6.27,-3.4,5.33)
bpy.context.object.rotation_euler = (1.172,0,0.907)
bpy.context.scene.render.resolution_x = 640
bpy.context.scene.render.resolution_y = 480
bpy.context.scene.render.resolution_percentage = 50
# Set the render engine (e.g., CYCLES, BLENDER_EEVEE)
bpy.context.scene.render.engine = 'CYCLES'
# Set the output file path
bpy.context.scene.render.filepath = './render2.png'
# Render the current view
bpy.ops.render.render(write_still=True)
import bpy
from math import pi
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物
bpy.ops.mesh.primitive_torus_add(major_radius=3.75, minor_radius=0.5)
bpy.context.object.location = (0, 0 ,4.5)
bpy.context.object.rotation_euler[1] = pi /2
mat = bpy.data.materials.new('mat_ring')
mat.use_nodes = True
color = (2,1,1,1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_torus_add(major_radius=0.5, minor_radius=0.3)
bpy.context.object.location = (0, 0 ,9)
mat = bpy.data.materials.new('mat_di')
mat.use_nodes = True
color = (2,2,1,1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=1, radius=1)
bpy.context.object.location = (0, 0 ,9.7)
mat = bpy.data.materials.new('mat_top')
mat.use_nodes = True
color = (1,2,2,1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_plane_add(size=20)
bpy.context.object.location = (0,0,0)
bpy.context.object.scale = (10,10,1)
camera = bpy.data.cameras.new('MyCamera')
camera_obj = bpy.data.objects.new('CameraObj', camera)
bpy.context.scene.collection.objects.link(camera_obj)
camera.lens = 30 # Focal length in millimeters
camera_obj.location = (10,8,19) # X, Y, Z coordinates
camera_obj.rotation_euler = (4,-9.5,5.3)
bpy.context.scene.camera = camera_obj
bpy.ops.object.light_add(type='SPOT', radius=1)
light = bpy.context.object
light.data.energy = 2000
light.location = (6.7,-3,15)
light.rotation_mode = 'XYZ'
light.rotation_euler = (7, 0, 1) import bpy
import math
# 删除所有现有对象
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
# 创建剑刃 (素模)
bpy.ops.mesh.primitive_cone_add(vertices=4, depth=4.0, radius1=0.1, radius2=0, location=(0, 0, 1.3))
blade = bpy.context.object
blade.scale = (0.5, 0.1, 0.6)
blade.rotation_euler = (0, 0, math.radians(90))
blade.name = 'Blade'
# 创建护手 (素模)
bpy.ops.mesh.primitive_cylinder_add(vertices=16, depth=0.2, radius=0.7, location=(0, 0, 0.1))
guard = bpy.context.object
guard.scale = (0.2, 0.1, 0.1)
guard.rotation_euler = (0, 0, math.radians(90))
guard.name = 'Guard'
# 创建剑柄 (素模)
bpy.ops.mesh.primitive_cylinder_add(vertices=16, depth=1.2, radius=0.3, location=(0, 0, -0.2))
hilt = bpy.context.object
hilt.scale = (0.1, 0.1, 0.5)
hilt.rotation_euler = (0, 0, 0)
hilt.name = 'Hilt'
# 创建剑柄末端的饰品 (素模)
bpy.ops.mesh.primitive_uv_sphere_add(segments=32, ring_count=16, radius=0.1, location=(0, 0, -0.5))
pommel = bpy.context.object
pommel.scale = (0.5, 0.5, 0.5)
pommel.name = 'Pommel'
# 剑的材质 (彩模)
material_blade = bpy.data.materials.new(name='BladeMaterial')
material_blade.diffuse_color = (0.8, 0.8, 0.9, 1) # 银色
blade.data.materials.append(material_blade)
material_guard = bpy.data.materials.new(name='GuardMaterial')
material_guard.diffuse_color = (0.8, 0.7, 0.0, 1) # 金色
guard.data.materials.append(material_guard)
material_hilt = bpy.data.materials.new(name='HiltMaterial')
material_hilt.diffuse_color = (0.2, 0.1, 0.0, 1) # 深棕色
hilt.data.materials.append(material_hilt)
material_pommel = bpy.data.materials.new(name='PommelMaterial')
material_pommel.diffuse_color = (0.8, 0.7, 0.0, 1) # 金色
pommel.data.materials.append(material_pommel)
# 创建一个平面作为地面
bpy.ops.mesh.primitive_plane_add(size=10, location=(0, 0, -2))
ground = bpy.context.object
ground.name = 'Ground'
material_ground = bpy.data.materials.new(name='GroundMaterial')
material_ground.diffuse_color = (0.2, 0.2, 0.2, 1)
ground.data.materials.append(material_ground)
# 设置相机
bpy.ops.object.camera_add(location=(2.65, -2.55, 5), rotation=(math.radians(44), 0, math.radians(46)))
camera = bpy.context.object
bpy.context.scene.camera = camera
# 设置灯光
bpy.ops.object.light_add(type='SUN', location=(5, -5, 5))
light = bpy.context.object
light.data.energy = 5
# 设置渲染设置
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.device = 'GPU' # 如果使用 GPU 渲染
bpy.context.scene.render.resolution_x = 1920
bpy.context.scene.render.resolution_y = 1080
bpy.context.scene.render.filepath = '/tmp/holy_sword_render_white.png'
# 渲染图像
bpy.ops.render.render(write_still=True)
import bpy
from math import pi
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物体
bpy.ops.mesh.primitive_plane_add(size = 1000)
bpy.context.object.location = (0,0,-25)
bpy.ops.mesh.primitive_cylinder_add(radius=1, depth=18)
bpy.context.object.location = (0,0,0)
bpy.context.object.rotation_euler[0] = pi /2
mat = bpy.data.materials.new('mat_1')
mat.use_nodes = True
color = (0.266, 1.01, 1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=2)
bpy.context.object.scale = (0.2,0.75,1)
bpy.context.object.rotation_euler[0] = - pi / 4
bpy.context.object.location = (0, 5 ,1)
mat = bpy.data.materials.new('mat_2')
mat.use_nodes = True
color = (0.266, 1.01, 1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=2)
bpy.context.object.scale = (0.2,0.75,1)
bpy.context.object.rotation_euler[0] = - pi / -4
bpy.context.object.location = (0, 5 ,-1)
mat = bpy.data.materials.new('mat_3')
mat.use_nodes = True
color = (0.266, 1.01, 1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=3)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / -4
bpy.context.object.location = (0, 7 ,-1)
mat = bpy.data.materials.new('mat_4')
mat.use_nodes = True
color = (0.266, 0.8, 1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=3)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.location = (0, 7 ,1)
bpy.context.object.rotation_euler[0] = - pi / 4
mat = bpy.data.materials.new('mat_4')
mat.use_nodes = True
color = (0.266, 0.8, 1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=6)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / 4
bpy.context.object.location = (0, 11 ,1)
mat = bpy.data.materials.new('mat_5')
mat.use_nodes = True
color = (0.783, 0.8, 0, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=6)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / -4
bpy.context.object.location = (0, 11 ,-1)
mat = bpy.data.materials.new('mat_6')
mat.use_nodes = True
color = (0, 0.479, 0.8, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=6)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / -4
bpy.context.object.location = (0, 11 ,-1)
bpy.ops.mesh.primitive_cube_add(size=6)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / 4
bpy.context.object.location = (0, 15 ,-1)
mat = bpy.data.materials.new('mat_7')
mat.use_nodes = True
color = (0.801, 0, 0.0026, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=6)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / -4
bpy.context.object.location = (0, 15 ,1)
mat = bpy.data.materials.new('mat_8')
mat.use_nodes = True
color = (0, 0.800, 0.08, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=16)
bpy.context.object.scale = (0.1,0.2,1.5)
bpy.context.object.rotation_euler[0] = - pi / 1
bpy.context.object.location = (0, -6 ,0)
mat = bpy.data.materials.new('mat_9')
mat.use_nodes = True
color = (0, 0.479, 0.8, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=10)
bpy.context.object.scale = (0.2,0.2,1.5)
bpy.context.object.rotation_euler[0] = - pi / 1
bpy.context.object.location = (0, -6 ,0)
mat = bpy.data.materials.new('mat_10')
mat.use_nodes = True
color = (0, 0.8, 0.744, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=4)
bpy.context.object.scale = (0.8,1,1.5)
bpy.context.object.rotation_euler[0] = - pi / 1
bpy.context.object.location = (0, -6 ,10)
mat = bpy.data.materials.new('mat_11')
mat.use_nodes = True
color = (0, 0.479, 0.8, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=4)
bpy.context.object.scale = (0.8,1,1.5)
bpy.context.object.rotation_euler[0] = - pi / 1
bpy.context.object.location = (0, -6 ,-10)
mat = bpy.data.materials.new('mat_12')
mat.use_nodes = True
color = (0, 0.479, 0.8, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=50)
bpy.context.object.scale = (0.04,0.15,1)
bpy.context.object.rotation_euler[0] = - pi / 2
bpy.context.object.location = (0, -31 ,0)
mat = bpy.data.materials.new('mat_13')
mat.use_nodes = True
color = (0, 0.479, 0.8, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=6)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / -2
bpy.context.object.location = (0, -6 ,-11)
mat = bpy.data.materials.new('mat_14')
mat.use_nodes = True
color = (0.10464, 0.0862603, 0.800797, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=6)
bpy.context.object.scale = (0.2,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / -2
bpy.context.object.location = (0, -6 ,11)
mat = bpy.data.materials.new('mat_15')
mat.use_nodes = True
color = (0.10464, 0.0862603, 0.800797, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=28)
bpy.context.object.scale = (0.12,0.08,1.9)
bpy.context.object.rotation_euler[0] = - pi / 2
bpy.context.object.location = (0, -32 ,0)
mat = bpy.data.materials.new('mat_16')
mat.use_nodes = True
color = (0, 0.8, 0.744, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=5.5)
bpy.context.object.scale = (0.35,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / 4
bpy.context.object.location = (0, -57 ,1)
mat = bpy.data.materials.new('mat_13')
mat.use_nodes = True
color = (0, 0.479, 0.8, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cube_add(size=5.5)
bpy.context.object.scale = (0.35,0.5,1)
bpy.context.object.rotation_euler[0] = - pi / -4
bpy.context.object.location = (0, -57 ,-1)
mat = bpy.data.materials.new('mat_13')
mat.use_nodes = True
color = (0, 0.479, 0.8, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
camera = bpy.data.cameras.new('Camera')
camera_obj = bpy.data.objects.new('Camera', camera)
bpy.data.collections["Collection"].objects.link(camera_obj)
camera.lens = 40 # Focal length in millimeters
camera.sensor_width = 36 # Sensor width in millimeters
camera.sensor_height = 24 # Sensor height in millimeters
camera_obj.location = (50.623, -78.94, 30.428) # X, Y, Z coordinates
camera_obj.rotation_euler = (0,149.6,-135.9)
bpy.context.scene.camera = camera_obj
bpy.ops.object.light_add(type='SPOT', radius=3)
bpy.context.object.data.energy = 1000
bpy.context.object.location = (50.623,-78.94,30.428)
bpy.context.object.rotation_euler = (67.85,0,54)
bpy.context.scene.render.resolution_x = 740
bpy.context.scene.render.resolution_y = 1080
bpy.context.scene.render.resolution_percentage = 50
# Set the render engine (e.g., CYCLES, BLENDER_EEVEE)
bpy.context.scene.render.engine = 'CYCLES'
# Set the output file path
bpy.context.scene.render.filepath = '/tmp/render2.png'
# Render the current view
bpy.ops.render.render(write_still=True)
import bpy
from math import pi
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物
bang = bpy.data.objects.new("bang", None)
bpy.data.collections["Collection"].objects.link(bang)
bpy.ops.mesh.primitive_cylinder_add(radius=0.3, depth=7)
bpy.context.object.rotation_euler[0] = pi /2
mat = bpy.data.materials.new('mat_bang1')
mat.use_nodes = True
color = (1,1.1,0.8,1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cylinder_add(radius=0.5, depth=25)
bpy.context.object.rotation_euler[2] = pi /2
bpy.context.object.location = (0, 0 ,-10.5)
bpy.context.object.name = "gan"
mat = bpy.data.materials.new('mat_bang2')
mat.use_nodes = True
color = (1,1.1,0.8,1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_monkey_add(size=5)
bpy.context.object.location = (0, 0 ,3)
bpy.context.object.rotation_euler[2] = pi /2
bpy.context.object.rotation_euler[0] = -pi /8
bpy.context.object.name = "head"
mat = bpy.data.materials.new('mat_head')
mat.use_nodes = True
color = (1,2,2,1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
empty_obj = bpy.data.objects.new("empty", None)
empty_obj.name = "xiangquan"
bpy.data.collections["Collection"].objects.link(empty_obj)
bpy.ops.mesh.primitive_torus_add(major_radius=3.75, minor_radius=0.25)
bpy.context.object.location = (0.25, 0 ,0.25)
bpy.context.object.rotation_euler[1] = pi /8
bpy.context.object.parent = empty_obj
bpy.context.object.name = "out"
mat = bpy.data.materials.new('mat_huan1')
mat.use_nodes = True
color = (2, 2,1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_torus_add(major_radius=2.4, minor_radius=0.35)
bpy.context.object.location = (0.25, 0 ,0.25)
bpy.context.object.rotation_euler[1] = pi /8
bpy.context.object.parent = empty_obj
bpy.context.object.name = "middle"
mat = bpy.data.materials.new('mat_huan2')
mat.use_nodes = True
color = (2, 1,1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_torus_add(major_radius=1.25, minor_radius=0.5)
bpy.context.object.location = (0.25, 0 ,0.25)
bpy.context.object.rotation_euler[1] = pi /8
bpy.context.object.parent = empty_obj
bpy.context.object.name = "in"
mat = bpy.data.materials.new('mat_huan2')
mat.use_nodes = True
color = (2, 1,4, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
empty_obj = bpy.data.objects.new("empty", None)
empty_obj.name = "king"
bpy.data.collections["Collection"].objects.link(empty_obj)
bpy.ops.mesh.primitive_torus_add(major_radius=1.25, minor_radius=0.3)
bpy.context.object.location = (-1, 0 ,5)
bpy.context.object.rotation_euler[1] = -pi /8
bpy.context.object.parent = empty_obj
bpy.context.object.name = "bottom"
mat = bpy.data.materials.new('mat_di')
mat.use_nodes = True
color = (1, 1,1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=1, radius=0.75)
bpy.context.object.location = (-1.25, 0 ,6)
bpy.context.object.parent = empty_obj
bpy.context.object.name = "top"
mat = bpy.data.materials.new('mat_zuan')
mat.use_nodes = True
color = (2,4,2, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cone_add(radius1=0.4, radius2=0, depth=0.8)
bpy.context.object.location = (-0.1, 0 ,5.8)
bpy.context.object.rotation_euler[1] = -pi /8
bpy.context.object.parent = empty_obj
bpy.context.object.name = "middle"
mat = bpy.data.materials.new('mat_zhong')
mat.use_nodes = True
color = (3, 2,0.2, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cone_add(radius1=0.4, radius2=0, depth=0.6)
bpy.context.object.location = (-0.1, 0.3 ,5.8)
bpy.context.object.rotation_euler[1] = -pi /8
bpy.context.object.parent = empty_obj
bpy.context.object.name = "left"
mat = bpy.data.materials.new('mat_zuo')
mat.use_nodes = True
color = (3, 2,1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cone_add(radius1=0.4, radius2=0, depth=0.6)
bpy.context.object.location = (-0.1, -0.3 ,5.8)
bpy.context.object.rotation_euler[1] = -pi /8
bpy.context.object.parent = empty_obj
bpy.context.object.name = "right"
mat = bpy.data.materials.new('mat_you')
mat.use_nodes = True
color = (3, 2,1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
empty_obj = bpy.data.objects.new("empty", None)
empty_obj.name = "erhuan"
bpy.data.collections["Collection"].objects.link(empty_obj)
bpy.ops.mesh.primitive_cone_add(radius1=0.25, radius2=0, depth=0.6)
bpy.context.object.location = (-0.9, -2.5 ,1.75)
bpy.context.object.rotation_euler[0] = pi
bpy.context.object.parent = empty_obj
bpy.context.object.name = "zuoer1"
mat = bpy.data.materials.new('mat_zuoer1')
mat.use_nodes = True
color = (4, 4,4, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cone_add(radius1=0.25, radius2=0, depth=0.6)
bpy.context.object.location = (-0.9, 2.5 ,1.75)
bpy.context.object.rotation_euler[0] = pi
bpy.context.object.parent = empty_obj
bpy.context.object.name = "youer1"
mat = bpy.data.materials.new('mat_youer1')
mat.use_nodes = True
color = (4, 4,4, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cylinder_add(radius=0.03, depth=0.5)
bpy.context.object.location = (-0.9, -2.5 ,2.25)
bpy.context.object.parent = empty_obj
bpy.context.object.name = "zuoer2"
mat = bpy.data.materials.new('mat_zhu1')
mat.use_nodes = True
color = (1,4,1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_cylinder_add(radius=0.03, depth=0.5)
bpy.context.object.location = (-0.9, 2.5 ,2.25)
bpy.context.object.parent = empty_obj
bpy.context.object.name = "youer2"
mat = bpy.data.materials.new('mat_zhu2')
mat.use_nodes = True
color = (1,4,1, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.ops.mesh.primitive_plane_add(size=60)
bpy.context.object.location = (0,0,-23)
camera = bpy.data.cameras.new('MyCamera')
camera_obj = bpy.data.objects.new('CameraObj', camera)
bpy.context.scene.collection.objects.link(camera_obj)
camera.lens = 14 # Focal length in millimeters
camera_obj.location = (10,4,9) # X, Y, Z coordinates
camera_obj.rotation_euler = (4,-9.5,5.3)
bpy.context.scene.camera = camera_obj
bpy.ops.object.light_add(type='SPOT', radius=1)
light = bpy.context.object
light.data.energy = 1000
light.location = (6.27, -3.4,11)
light.rotation_mode = 'XYZ'
light.rotation_euler = (7, 0, 1)
bpy.context.scene.render.resolution_x = 800
bpy.context.scene.render.resolution_y = 600
bpy.context.scene.render.resolution_percentage = 100
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.render.resolution_x = 1920
bpy.context.scene.render.resolution_y = 1080
bpy.context.scene.render.resolution_percentage = 100
bpy.context.scene.render.filepath = "/tmp/xuanran.png"
bpy.context.scene.render.image_settings.file_format = 'PNG'
bpy.context.scene.render.image_settings.color_mode = 'RGBA'
bpy.ops.render.render(write_still=True)
import bpy
import random
import math
# 清除当前场景
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
# 创建糖葫芦串(竹签)
bpy.ops.mesh.primitive_cylinder_add(radius=0.1, depth=10, location=(0, 0, 0))
stick = bpy.context.object
stick.name = "Stick"
stick.data.materials.append(bpy.data.materials.new(name="StickMaterial"))
stick.data.materials[0].diffuse_color = (0.5, 0.3, 0, 1)
# 创建糖葫芦(山楂)
berries = []
for i in range(5):
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.5, location=(0, 0, i * 1.2))
berry = bpy.context.object
berry.name = f"Berry_{i + 1}"
# 创建并应用材质
mat_name = f"BerryMaterial_{i + 1}"
mat = bpy.data.materials.new(name=mat_name)
mat.use_nodes = True
berry.data.materials.append(mat)
mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.8, 0, 0, 1)
# 添加糖衣效果
mat.metallic = 0.3
mat.roughness = 0.2
# 添加随机偏移
berry.location.x += random.uniform(-0.05, 0.05)
berry.location.y += random.uniform(-0.05, 0.05)
# 设置父对象
berry.parent = stick
berries.append(berry)
# 添加相机和光源
bpy.ops.object.camera_add(location=(5, -5, 5))
camera = bpy.context.object
camera.rotation_euler = (math.radians(60), 0, math.radians(45))
bpy.ops.object.light_add(type='SUN', location=(5, 5, 10))
sun = bpy.context.object
sun.data.energy = 5
# 更新视图
bpy.context.view_layer.update()
import bpy
import math
# clear current scene
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
# body
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(0, 0, 0))
body = bpy.context.object
body.name = "body"
body.scale = (1, 1.3, 1)
# 创建并设置 body 材质
body_mat = bpy.data.materials.new(name="bodyMaterial")
body_mat.use_nodes = True
bsdf_node = body_mat.node_tree.nodes.get('Principled BSDF') or body_mat.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
body_mat.node_tree.nodes.remove(bsdf_node)
bsdf_node = body_mat.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
body_mat.node_tree.links.new(body_mat.node_tree.nodes['Material Output'].inputs['Surface'], bsdf_node.outputs['BSDF'])
bsdf_node.inputs['Base Color'].default_value = (1, 0.08, 0.03, 1)
body.data.materials.append(body_mat)
# top cylinder
bpy.ops.mesh.primitive_cylinder_add(radius=0.5, depth=0.2, location=(0, 0, 0.97))
body1 = bpy.context.object
body1.name = "body1"
# 创建并设置 top cylinder 材质
top_mat = bpy.data.materials.new(name="topMaterial")
top_mat.use_nodes = True
bsdf_node = top_mat.node_tree.nodes.get('Principled BSDF') or top_mat.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
if bsdf_node:
bsdf_node.inputs['Base Color'].default_value = (1, 0.66, 0.06, 1)
body1.data.materials.append(top_mat)
body1.parent = bpy.data.objects['body']
# bottom cylinder
bpy.ops.mesh.primitive_cylinder_add(radius=0.5, depth=0.2, location=(0, 0, -0.97))
body2 = bpy.context.object
body2.name = "body2"
# 创建并设置 bottom cylinder 材质
bottom_mat = bpy.data.materials.new(name="bottomMaterial")
bottom_mat.use_nodes = True
bsdf_node = bottom_mat.node_tree.nodes.get('Principled BSDF') or bottom_mat.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
if bsdf_node:
bsdf_node.inputs['Base Color'].default_value = (1, 0.66, 0.06, 1)
body2.data.materials.append(bottom_mat)
body2.parent = bpy.data.objects['body']
# torus
bpy.ops.mesh.primitive_torus_add(
location=(0, 0, 1),
rotation=(1.5708, 0, 1.5708),
major_radius=1,
minor_radius=0.25
)
body3 = bpy.context.object
body3.name = "body3"
body3.scale = (0.1, 0.3, 0.2)
# 创建并设置 torus 材质
torus_mat = bpy.data.materials.new(name="torusMaterial")
torus_mat.use_nodes = True
bsdf_node = torus_mat.node_tree.nodes.get('Principled BSDF') or torus_mat.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
if bsdf_node:
bsdf_node.inputs['Base Color'].default_value = (1, 0.08, 0.03, 1)
body3.data.materials.append(torus_mat)
body3.parent = bpy.data.objects['body']
# 创建须须
num_tassels = 12
radius = 0.4
tassel_length = 0.8
tassel_radius = 0.05
# 预创建须须材质
tassel_mat = bpy.data.materials.new(name="tasselMaterial")
tassel_mat.use_nodes = True
bsdf_node = tassel_mat.node_tree.nodes.get('Principled BSDF') or tassel_mat.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
if bsdf_node:
bsdf_node.inputs['Base Color'].default_value = (1, 0.08, 0.03, 1)
for i in range(num_tassels):
angle = (2 * math.pi / num_tassels) * i
x = radius * math.cos(angle)
y = radius * math.sin(angle)
z = -1.1
bpy.ops.mesh.primitive_cylinder_add(radius=tassel_radius, depth=tassel_length, location=(x, y, z))
tassel = bpy.context.object
tassel.name = f"Tassel_{i+1}"
tassel.data.materials.append(tassel_mat)
# 设置相机和灯光
bpy.ops.object.camera_add(location=(8.6, 1.43, 0), rotation=(1.5708, 0, 1.72788))
camera = bpy.context.object
bpy.context.scene.camera = camera
bpy.ops.object.light_add(type='SPOT', location=(7.9, -0.5, 3))
light = bpy.context.object
light.rotation_euler = (0.279253, 1.06465, 6.519)
light.data.energy = 1000
import bpy
from math import pi
# 选择并删除场景中所有对象
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# 创建头部
bpy.ops.mesh.primitive_uv_sphere_add()
head = bpy.context.object
head.name = "head"
yellow = bpy.data.materials.new('yellow_head')
color = (0.9, 0.5, 0, 1)
yellow.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(yellow)
bpy.context.object.location = (0, 0, 0.2)
bpy.context.object.scale = (1.5, 1.5, 1.2)
# 创建左眼
eye1 = bpy.ops.mesh.primitive_uv_sphere_add()
bpy.context.object.name = "eye1"
bpy.context.object.location = (0.9, 0, -0.1)
bpy.context.object.scale = (0.25, 0.25, 0.25)
mat = bpy.data.materials.new('mat_eye')
mat.use_nodes = True
color = (0, 0, 0, 1)
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
bpy.context.object.data.materials.append(mat)
bpy.context.object.parent = head
# 创建右眼
eye2 = bpy.ops.mesh.primitive_uv_sphere_add()
bpy.context.object.name = "eye2"
bpy.context.object.location = (-0.9, 0, -0.1)
bpy.context.object.scale = (0.25, 0.25, 0.25)
bpy.context.object.data.materials.append(mat)
bpy.context.object.parent = head
# 创建line部件
bpy.ops.mesh.primitive_uv_sphere_add()
bpy.context.object.location = (0, 0, -0.1)
bpy.context.object.scale = (1.0, 0.3, 1.0)
bpy.context.object.data.materials.append(mat)
bpy.context.object.parent = head
bpy.context.object.name = "line"
# 创建circle部件
bpy.ops.mesh.primitive_torus_add()
bpy.context.object.location = (0, 0, 0.2)
bpy.context.object.scale = (0.9, 0.9, 0.5)
bpy.context.object.data.materials.append(yellow)
bpy.context.object.parent = head
bpy.context.object.name = "circle"
# 创建circle2部件
bpy.ops.mesh.primitive_torus_add()
bpy.context.object.location = (0, 0.1, 0.2)
bpy.context.object.scale = (0.2, 0.2, 0.2)
bpy.context.object.data.materials.append(yellow)
bpy.context.object.parent = head
bpy.context.object.rotation_euler[1] = pi / 2
bpy.context.object.name = "circle2"
import bpy
import math
# 删除场景中的所有对象
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
# 创建蛋糕的层
def create_cake_layer(radius, height, location):
bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=radius, depth=height, location=location)
return bpy.context.object
# 创建蛋糕的糖霜
def create_frosting(radius, thickness, location):
bpy.ops.mesh.primitive_torus_add(major_radius=radius, minor_radius=thickness, location=location)
return bpy.context.object
# 创建蜡烛
def create_candle(radius, height, location):
bpy.ops.mesh.primitive_cylinder_add(vertices=16, radius=radius, depth=height, location=location)
return bpy.context.object
# 设置蛋糕的参数
layer_radius = 2.0
layer_height = 0.5
frosting_thickness = 0.1
candle_radius = 0.05
candle_height = 1.0
# 创建蛋糕的层
layer1 = create_cake_layer(layer_radius, layer_height, (0, 0, layer_height / 2))
layer2 = create_cake_layer(layer_radius * 0.8, layer_height, (0, 0, layer_height + layer_height / 2))
layer3 = create_cake_layer(layer_radius * 0.6, layer_height, (0, 0, 2 * layer_height + layer_height / 2))
# 创建糖霜
frosting1 = create_frosting(layer_radius, frosting_thickness, (0, 0, layer_height))
frosting2 = create_frosting(layer_radius * 0.8, frosting_thickness, (0, 0, 2 * layer_height))
frosting3 = create_frosting(layer_radius * 0.6, frosting_thickness, (0, 0, 3 * layer_height))
# 创建蜡烛
candle1 = create_candle(candle_radius, candle_height, (0, 0, 3 * layer_height + candle_height / 2))
candle2 = create_candle(candle_radius, candle_height, (0.5, 0.5, 3 * layer_height + candle_height / 2))
candle3 = create_candle(candle_radius, candle_height, (-0.5, -0.5, 3 * layer_height + candle_height / 2))
# 设置材质(可选)
def set_material(obj, color):
mat = bpy.data.materials.new(name="Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
obj.data.materials.append(mat)
# 设置所有蛋糕层为黄色
set_material(layer1, (1, 0.8, 0.3, 1)) # 蛋糕层颜色 - 黄色
set_material(layer2, (1, 0.8, 0.3, 1)) # 蛋糕层颜色 - 黄色
set_material(layer3, (1, 0.8, 0.3, 1)) # 蛋糕层颜色 - 黄色
# 设置所有糖霜为白色
set_material(frosting1, (1, 1, 1, 1)) # 糖霜颜色
set_material(frosting2, (1, 1, 1, 1)) # 糖霜颜色
set_material(frosting3, (1, 1, 1, 1)) # 糖霜颜色
# 设置所有蜡烛为红色
set_material(candle1, (1, 0, 0, 1)) # 蜡烛颜色
set_material(candle2, (1, 0, 0, 1)) # 蜡烛颜色
set_material(candle3, (1, 0, 0, 1)) # 蜡烛颜色
# 输出信息
print("蛋糕已生成!")
# 取消选择所有物体
bpy.ops.object.select_all(action='DESELECT')
# 选择场景中的所有物体
for obj in bpy.context.scene.objects:
obj.select_set(True)
# 设置最后一个选中的物体为活动物体
bpy.context.view_layer.objects.active = bpy.context.selected_objects[-1]
# 合并所有选中的物体
bpy.ops.object.join()import bpy
# 清空场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# 定义圣诞树的层数和参数
num_layers = 3
layer_height = 1.3 # 每层的高度
base_radius = 0.2 # 底部圆柱体的半径
tree = bpy.data.objects.new("tree", None)
bpy.data.collections["Collection"].objects.link(tree)
# 创建圣诞树的主干(圆柱体)
bpy.ops.mesh.primitive_cylinder_add(radius=base_radius, depth=num_layers * layer_height, location=(0, 0, 0))
trunk = bpy.context.object
trunk.parent = tree
# 创建圣诞树的第一层树冠(圆台)
bottom_radius1 = 1.2 # 第一层底部圆台的底半径
top_radius1 = 0.3 # 第一层底部圆台的顶半径
height1 = 1.0 # 第一层底部圆台的高度
bpy.ops.mesh.primitive_cone_add(vertices=32, radius1=bottom_radius1, radius2=top_radius1, depth=height1, location=(0, 0, height1 / 2))
tree_top1 = bpy.context.object
tree_top1.parent = tree
# 创建圣诞树的第二层树冠(圆台)
bottom_radius2 = 0.8 # 第二层底部圆台的底半径
top_radius2 = 0.1 # 第二层底部圆台的顶半径
height2 = 1.0 # 第二层底部圆台的高度
bpy.ops.mesh.primitive_cone_add(vertices=32, radius1=bottom_radius2, radius2=top_radius2, depth=height2, location=(0, 0, height1 + height2 / 2))
tree_top2 = bpy.context.object
tree_top2.parent = tree
# 创建圣诞树的第三层树冠(圆锥体)
bottom_radius3 = 0.5 # 第三层底部圆锥体的底半径
height3 = 1.0 # 第三层底部圆锥体的高度
bpy.ops.mesh.primitive_cone_add(vertices=32, radius1=bottom_radius3, depth=height3, location=(0, 0, height1 + height2 + height3 / 2 - 0.3)) # 往下移动一些,与第二层圆台贴合
tree_top3 = bpy.context.object
tree_top3.parent = tree
# 设置圣诞树的材质
mat_green = bpy.data.materials.new(name="GreenMaterial")
mat_green.diffuse_color = (0.1, 0.5, 0.1, 1.0) # 绿色
trunk.data.materials.append(mat_green)
tree_top1.data.materials.append(mat_green)
tree_top2.data.materials.append(mat_green)
tree_top3.data.materials.append(mat_green)
bpy.ops.mesh.primitive_plane_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.location[2] = -2
bpy.context.object.scale = (10,10,1)
bpy.ops.object.light_add(type='SPOT', radius=1)
light = bpy.context.object
light.name = "Light"
light.data.energy = 1000
light.location = (2.100301504135132, -2.5599961280822754, 4.457478046417236)
light.rotation_euler = (0.6562445163726807, 8.790517114221075e-08, 0.48171061277389526)
bpy.ops.object.camera_add()
camera = bpy.context.object
camera.location = (-6.545682430267334, -6.106528282165527, 7.655974388122559)
camera.rotation_euler = (0.8726650476455688, 3.8112457900751906e-07, -0.760964035987854)
bpy.context.scene.camera = camera
bpy.context.scene.render.resolution_x = 640
bpy.context.scene.render.resolution_y = 480
bpy.context.scene.render.resolution_percentage = 50
bpy.context.scene.render.filepath = "/tmp/my_render_output.png"
bpy.ops.render.render(write_still=True)
import bpy
def create_material(name, color):
mat = bpy.data.materials.new(name)
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
return mat
def create_tree():
# 清除场景
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
# 创建空物体作为父对象
bpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))
tree = bpy.context.active_object
tree.name = "Tree"
# 创建材质
trunk_mat = create_material('trunk', (0.3, 0.15, 0.05, 1))
crown_mat = create_material('crown', (0, 1, 0.4, 1))
# 创建树干
bpy.ops.mesh.primitive_cone_add()
trunk = bpy.context.object
trunk.name = "trunk"
trunk.scale = (0.5, 0.5, 1)
trunk.data.materials.append(trunk_mat)
trunk.parent = tree
# 创建树枝
branches = [
("branch1", (-0.47, 0, 0.5), (0.2, 0.2, 0.5), (0.3, 0.7, 3.5)),
("branch2", (0.47, -0.1, 0.3), (0.2, 0.2, 0.5), (0.5, 0.3, 0.7))
]
for name, loc, scale, rot in branches:
bpy.ops.mesh.primitive_cone_add()
branch = bpy.context.object
branch.name = name
branch.location = loc
branch.scale = scale
branch.rotation_euler = rot
branch.data.materials.append(trunk_mat)
branch.parent = tree
# 创建树冠
crowns = [
("crown1", (0, 0, 1.5), (0.8, 0.8, 0.8)),
("crown2", (-1, 0, 0.7), (0.6, 0.6, 0.6)),
("crown3", (0.8, 0, 1), (0.5, 0.5, 0.5)),
("crown4", (-0.7, 0.5, 1.4), (0.4, 0.4, 0.4)),
("crown5", (0.7, -0.2, 0.5), (0.3, 0.3, 0.3))
]
for name, loc, scale in crowns:
bpy.ops.mesh.primitive_uv_sphere_add()
crown = bpy.context.object
crown.name = name
crown.location = loc
crown.scale = scale
crown.data.materials.append(crown_mat)
crown.parent = tree
return tree
if __name__ == "__main__":
create_tree()
import bpy
import math
import random
def create_material(name, color):
material = bpy.data.materials.new(name=name)
material.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = color
return material
def create_tree(location):
# 创建树干
trunk_height = random.uniform(2, 5)
bpy.ops.mesh.primitive_cylinder_add(radius=0.1, depth=trunk_height,
location=(location[0], location[1], trunk_height/2))
trunk = bpy.context.active_object
trunk.data.materials.append(create_material("TrunkMaterial", (0.5, 0.3, 0.1, 1)))
# 创建树冠
crown_radius = random.uniform(0.5, 1.5)
bpy.ops.mesh.primitive_uv_sphere_add(radius=crown_radius,
location=(location[0], location[1], trunk_height + crown_radius))
crown = bpy.context.active_object
crown.data.materials.append(create_material("CrownMaterial", (0.1, 0.7, 0.1, 1)))
return trunk, crown
def create_scene():
# 清空场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# 创建树
trees = []
for i in range(10):
trees.extend(create_tree((i * 2, 0, 0)))
return trees
if __name__ == "__main__":
create_scene()
import bpy
import math
import random
import mathutils
# ========== 设置基本参数 ==========
FPS = 24
DURATION_SEC = 3
scene = bpy.context.scene
scene.frame_start = 1
scene.frame_end = FPS * DURATION_SEC
scene.render.fps = FPS
# ========== 清空场景 ==========
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# ========== 创建沙滩 ==========
bpy.ops.mesh.primitive_plane_add(size=50, location=(0, 0, 0))
beach = bpy.context.active_object
beach.name = "Beach"
sand_mat = bpy.data.materials.new(name="SandMaterial")
sand_mat.use_nodes = True
sand_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (1.0, 0.9, 0.6, 1)
beach.data.materials.append(sand_mat)
# ========== 创建太阳 ==========
bpy.ops.mesh.primitive_uv_sphere_add(radius=1.5, location=(7, 7, 6))
sun = bpy.context.active_object
sun.name = "Sun"
sun_mat = bpy.data.materials.new(name="SunMaterial")
sun_mat.use_nodes = True
sun_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (1.0, 1.0, 0.0, 1)
sun.data.materials.append(sun_mat)
# ========== 创建太阳光芒 ==========
num_rays = 16
ray_length = 1.2
sun_center = mathutils.Vector((7, 7, 6))
sun_radius = 1.5
ring_radius = sun_radius + 0.01
for i in range(num_rays):
angle = i * (2 * math.pi / num_rays)
x = sun_center.x + ring_radius * math.cos(angle)
y = sun_center.y
z = sun_center.z + ring_radius * math.sin(angle)
ray_pos = mathutils.Vector((x, y, z))
direction = (ray_pos - sun_center).normalized()
center_pos = ray_pos + direction * (ray_length / 2)
bpy.ops.mesh.primitive_cylinder_add(radius=0.05, depth=ray_length, location=center_pos)
ray = bpy.context.active_object
up = mathutils.Vector((0, 0, 1))
quat = up.rotation_difference(direction)
ray.rotation_mode = 'QUATERNION'
ray.rotation_quaternion = quat
ray.data.materials.append(sun_mat)
# ========== 创建树木 ==========
def add_tree(location):
x, y = location
bpy.ops.mesh.primitive_cylinder_add(radius=0.2, depth=2, location=(x, y, 1))
trunk = bpy.context.active_object
trunk_mat = bpy.data.materials.get("TrunkMaterial") or bpy.data.materials.new(name="TrunkMaterial")
trunk_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.55, 0.27, 0.07, 1)
trunk.data.materials.append(trunk_mat)
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.9 + random.uniform(0, 0.3), location=(x, y, 2.5))
leaves = bpy.context.active_object
leaves_mat = bpy.data.materials.get("LeavesMaterial") or bpy.data.materials.new(name="LeavesMaterial")
leaves_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.0, 0.6 + random.uniform(0, 0.2), 0.0, 1)
leaves.data.materials.append(leaves_mat)
tree_positions = [(-4, -3), (-2, 0), (0, -2), (2, 2), (4, -1), (6, 1)]
for pos in tree_positions:
add_tree(pos)
# ========== 创建动漫风云朵 ==========
def add_cartoon_cloud(center_location):
cx, cy, cz = center_location
cloud_mat = bpy.data.materials.get("CloudMaterial")
if not cloud_mat:
cloud_mat = bpy.data.materials.new(name="CloudMaterial")
cloud_mat.use_nodes = True
cloud_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (1, 1, 1, 1)
cloud_mat.use_nodes = False
cloud_parts = []
offsets = [
(-0.6, 0, 0, 0.7),
(-0.2, 0.3, 0, 0.8),
(0.3, 0, 0, 0.75),
(0.7, 0.2, 0, 0.6),
(0.1, -0.3, 0, 0.65),
]
for dx, dy, dz, radius in offsets:
bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, location=(cx + dx, cy + dy, cz + dz))
puff = bpy.context.active_object
puff.data.materials.append(cloud_mat)
cloud_parts.append(puff)
return cloud_parts
cloud_centers = [
(-5, -3, 6.0),
(-2, 4, 5.8),
(3, -4, 6.2),
(0, 5, 6.1),
(4, 2, 5.7),
(-3, 1, 6.3)
]
all_clouds = []
for pos in cloud_centers:
cloud_objs = add_cartoon_cloud(pos)
all_clouds.append(cloud_objs)
# ========== 设置蓝天背景 ==========
bpy.context.scene.world.use_nodes = True
world_nodes = bpy.context.scene.world.node_tree.nodes
bg_node = world_nodes.get("Background")
if bg_node:
bg_node.inputs[0].default_value = (0.2, 0.5, 0.9, 1)
bg_node.inputs[1].default_value = 1.2
# ========== 添加阳光 ==========
bpy.ops.object.light_add(type='SUN', location=(10, -10, 12))
sun_light = bpy.context.active_object
sun_light.data.energy = 5
sun_light.rotation_euler = (math.radians(50), 0, math.radians(45))
# ========== 添加摄像机,全景覆盖 ==========
bpy.ops.object.camera_add(location=(16.8, -22.6, 27.7), rotation=(0.84, 0 ,0.6))
camera = bpy.context.active_object
bpy.context.scene.camera = camera
# ========== 给云朵添加动画 ==========
def animate_cloud(cloud_objs, start_frame):
amplitude = 0.2 # 稍大幅度
period = scene.frame_end - scene.frame_start
for obj in cloud_objs:
for frame in range(scene.frame_start, scene.frame_end + 1, 4):
t = (frame - start_frame) / period * 2 * math.pi
offset = amplitude * math.sin(t)
obj.location.z += offset
obj.keyframe_insert(data_path="location", frame=frame)
obj.location.z -= offset
for i, cloud in enumerate(all_clouds):
animate_cloud(cloud, start_frame=1 + i * 4)import bpy
import math
import os
import random
print("=" * 50)
print("开始创建绝对有颜色的荷花场景...")
print("=" * 50)
# 清空场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
# ====================
# 1. 创建水面 - 蓝色
# ====================
print("创建蓝色水面...")
bpy.ops.mesh.primitive_plane_add(size=15, location=(0, 0, 0))
water = bpy.context.active_object
water.name = "Water_Blue"
# 使用节点创建水面材质
water_mat = bpy.data.materials.new(name="Water_Blue_Material")
water_mat.use_nodes = True
nodes = water_mat.node_tree.nodes
links = water_mat.node_tree.links
# 清空默认节点
nodes.clear()
# 创建必要的节点
output = nodes.new(type='ShaderNodeOutputMaterial')
principled = nodes.new(type='ShaderNodeBsdfPrincipled')
# 设置水面颜色为蓝色
principled.inputs['Base Color'].default_value = (0.1, 0.3, 0.8, 1.0) # 蓝色
principled.inputs['Roughness'].default_value = 0.1
# 连接节点
links.new(principled.outputs['BSDF'], output.inputs['Surface'])
# 应用材质
water.data.materials.append(water_mat)
# ====================
# 2. 创建荷叶 - 绿色
# ====================
print("创建绿色荷叶...")
def create_green_leaf(x, y, size=1.5):
bpy.ops.mesh.primitive_circle_add(
vertices=32,
radius=size,
fill_type='NGON',
location=(x, y, 0.1)
)
leaf = bpy.context.active_object
leaf.name = f"Leaf_Green_{x}_{y}"
# 使用节点创建荷叶材质
leaf_mat = bpy.data.materials.new(name=f"Leaf_Green_Material_{x}_{y}")
leaf_mat.use_nodes = True
nodes = leaf_mat.node_tree.nodes
links = leaf_mat.node_tree.links
# 清空默认节点
nodes.clear()
# 创建节点
output = nodes.new(type='ShaderNodeOutputMaterial')
principled = nodes.new(type='ShaderNodeBsdfPrincipled')
# 设置荷叶颜色为绿色
principled.inputs['Base Color'].default_value = (0.2, 0.6, 0.2, 1.0) # 绿色
principled.inputs['Roughness'].default_value = 0.3
# 连接节点
links.new(principled.outputs['BSDF'], output.inputs['Surface'])
# 应用材质
leaf.data.materials.append(leaf_mat)
# 稍微旋转
leaf.rotation_euler = (0, 0, random.uniform(0, math.pi*2))
return leaf
# 创建荷叶
leaf_positions = [
(4, 4, 1.8), (0, 5, 2.0), (-4, 4, 1.8),
(5, 0, 1.8), (-5, 0, 1.8),
(4, -4, 1.8), (0, -5, 2.0), (-4, -4, 1.8)
]
for x, y, size in leaf_positions:
create_green_leaf(x, y, size)
# ====================
# 3. 创建荷花 - 粉红色花瓣 + 黄色花心
# ====================
print("创建彩色荷花...")
def create_colorful_lotus(x, y):
# 创建花心 - 黄色
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.4, location=(x, y, 1.2))
center = bpy.context.active_object
center.name = f"Flower_Center_Yellow_{x}_{y}"
# 使用节点创建黄色花心材质
center_mat = bpy.data.materials.new(name=f"Center_Yellow_Material_{x}_{y}")
center_mat.use_nodes = True
nodes = center_mat.node_tree.nodes
links = center_mat.node_tree.links
nodes.clear()
output = nodes.new(type='ShaderNodeOutputMaterial')
principled = nodes.new(type='ShaderNodeBsdfPrincipled')
# 设置黄色
principled.inputs['Base Color'].default_value = (0.9, 0.8, 0.1, 1.0) # 黄色
principled.inputs['Roughness'].default_value = 0.2
links.new(principled.outputs['BSDF'], output.inputs['Surface'])
center.data.materials.append(center_mat)
# 创建花瓣 - 粉红色
for i in range(8):
angle = (i / 8) * math.pi * 2
bpy.ops.mesh.primitive_cone_add(
vertices=12,
radius1=0.5,
radius2=0.1,
depth=0.8,
location=(x, y, 1.2)
)
petal = bpy.context.active_object
petal.name = f"Petal_Pink_{i}_{x}_{y}"
# 调整位置和方向
petal.rotation_euler = (math.pi/2, 0, angle)
offset_x = math.cos(angle) * 0.8
offset_y = math.sin(angle) * 0.8
petal.location = (x + offset_x, y + offset_y, 1.3)
# 使用节点创建粉红色花瓣材质
petal_mat = bpy.data.materials.new(name=f"Petal_Pink_Material_{i}_{x}_{y}")
petal_mat.use_nodes = True
nodes = petal_mat.node_tree.nodes
links = petal_mat.node_tree.links
nodes.clear()
output = nodes.new(type='ShaderNodeOutputMaterial')
principled = nodes.new(type='ShaderNodeBsdfPrincipled')
# 设置粉红色
principled.inputs['Base Color'].default_value = (0.95, 0.7, 0.8, 1.0) # 粉红色
principled.inputs['Roughness'].default_value = 0.2
links.new(principled.outputs['BSDF'], output.inputs['Surface'])
petal.data.materials.append(petal_mat)
return center
# 创建4朵荷花
print("创建4朵彩色荷花...")
create_colorful_lotus(0, 0)
create_colorful_lotus(3, 3)
create_colorful_lotus(-3, 3)
create_colorful_lotus(3, -3)
# ====================
# 4. 创建茎杆 - 深绿色
# ====================
print("创建深绿色茎杆...")
def create_green_stem(flower_x, flower_y):
bpy.ops.mesh.primitive_cylinder_add(
vertices=8,
radius=0.1,
depth=1.1,
location=(flower_x, flower_y, 0.55)
)
stem = bpy.context.active_object
stem.name = f"Stem_DarkGreen_{flower_x}_{flower_y}"
# 使用节点创建茎杆材质
stem_mat = bpy.data.materials.new(name=f"Stem_DarkGreen_Material_{flower_x}_{flower_y}")
stem_mat.use_nodes = True
nodes = stem_mat.node_tree.nodes
links = stem_mat.node_tree.links
nodes.clear()
output = nodes.new(type='ShaderNodeOutputMaterial')
principled = nodes.new(type='ShaderNodeBsdfPrincipled')
# 设置深绿色
principled.inputs['Base Color'].default_value = (0.3, 0.5, 0.3, 1.0) # 深绿色
principled.inputs['Roughness'].default_value = 0.4
links.new(principled.outputs['BSDF'], output.inputs['Surface'])
stem.data.materials.append(stem_mat)
return stem
# 为每朵荷花创建茎杆
for flower_pos in [(0, 0), (3, 3), (-3, 3), (3, -3)]:
create_green_stem(flower_pos[0], flower_pos[1])
# ====================
# 5. 设置强力的灯光
# ====================
print("设置强力灯光...")
# 主光源
bpy.ops.object.light_add(type='SUN', location=(10, 10, 20))
sun = bpy.context.active_object
sun.name = "Main_Sun_Light"
sun.data.energy = 10.0 # 非常强的亮度
sun.rotation_euler = (math.radians(45), 0, math.radians(45))
# 填充光
bpy.ops.object.light_add(type='AREA', location=(0, 0, 15))
fill_light = bpy.context.active_object
fill_light.name = "Fill_Area_Light"
fill_light.data.energy = 500 # 极强的填充光
fill_light.data.size = 20
# ====================
# 6. 设置相机
# ====================
print("设置相机...")
bpy.ops.object.camera_add(location=(12, -12, 8))
camera = bpy.context.active_object
camera.name = "Main_Camera"
camera.rotation_euler = (math.radians(65), 0, math.radians(45))
bpy.context.scene.camera = camera
# ====================
# 7. 强制使用材质预览模式
# ====================
print("强制设置视图模式...")
# 直接操作3D视图的设置
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
for space in area.spaces:
if space.type == 'VIEW_3D':
# 强制设置为材质预览模式
space.shading.type = 'MATERIAL'
space.shading.light = 'STUDIO'
try:
space.shading.studio_light = 'studio.exr'
except TypeError:
# 如果 studio.exr 不存在,尝试使用第一个可用的 studio light
pass
space.shading.show_object_outline = True
space.shading.show_backface_culling = False
# 确保颜色显示设置
space.shading.color_type = 'MATERIAL'
space.shading.use_scene_lights = True
space.shading.use_scene_world = True
print("✅ 强制设置了材质预览模式")
break
break
# ====================
# 8. 检查所有材质是否已正确创建
# ====================
print("检查材质创建情况...")
material_count = len(bpy.data.materials)
print(f"✅ 已创建 {material_count} 个材质")
# ====================
# 9. 手动渲染一张图片验证颜色
# ====================
print("渲染验证图片...")
output_path = os.path.join(os.path.expanduser("~"), "Desktop", "Lotus_Colors_Verified")
os.makedirs(output_path, exist_ok=True)
# 设置渲染
scene = bpy.context.scene
# 使用CYCLES渲染器(颜色显示最准确)
try:
scene.render.engine = 'CYCLES'
print("使用渲染引擎: CYCLES")
scene.cycles.samples = 32 # 低采样以加快渲染
except:
try:
scene.render.engine = 'BLENDER_EEVEE'
print("使用渲染引擎: BLENDER_EEVEE")
except:
print("使用默认渲染引擎")
# 设置渲染参数
scene.render.resolution_x = 800
scene.render.resolution_y = 600
scene.render.image_settings.file_format = 'PNG'
scene.render.filepath = os.path.join(output_path, "lotus_colors_verified.png")
print("开始渲染验证图片...")
try:
bpy.ops.render.render(write_still=True)
print(f"✅ 验证图片已保存到: {scene.render.filepath}")
print(f"✅ 请查看这个图片确认颜色是否正确!")
except Exception as e:
print(f"⚠️ 渲染时出错: {e}")
print("=" * 50)
print("场景创建完成!")
print("=" * 50)
print("颜色方案:")
print(" 1. 🌊 水面: 蓝色")
print(" 2. 🍃 荷叶: 绿色")
print(" 3. 🌸 花心: 黄色")
print(" 4. 💮 花瓣: 粉红色")
print(" 5. 🌿 茎杆: 深绿色")
print("=" * 50)
print("如果视图中仍然看不到颜色:")
print(" 1. 按Z键 → 选择'渲染'模式")
print(" 2. 按F12键手动渲染")
print(" 3. 确保灯光强度足够")
print(" 4. 检查桌面上的验证图片")
print("=" * 50)
# 最后保存Blender文件
blend_file = os.path.join(output_path, "lotus_colors.blend")
try:
bpy.ops.wm.save_as_mainfile(filepath=blend_file)
print(f"✅ Blender文件已保存: {blend_file}")
except:
print("⚠️ 无法保存Blender文件")
print("=" * 50)
import bpy
import random
from math import pi
# 删除所有物体
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
# 创建墙体
width = 1.75
depth = 1.65
height = 1.5
bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, height/2))
wall = bpy.context.object
wall.name = "Wall"
wall.scale = (width, depth, height)
wall_mat = bpy.data.materials.new(name="BrownMaterial")
wall_mat.use_nodes = True
wall_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.5, 0.2, 0, 1)
wall.data.materials.append(wall_mat)
# 创建门
door_width = 0.5
door_height = 1
bpy.ops.mesh.primitive_cube_add(size=1, location=(-0.65, -0.4, 0.5))
door = bpy.context.object
door.name = "Door"
door.scale = (door_width, door_width, door_height)
door_mat = bpy.data.materials.new(name="BlackMaterial")
door_mat.use_nodes = True
door_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0, 0, 0, 0.9)
door.data.materials.append(door_mat)
# 创建门把手
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.03, location=(-0.91, -0.23, 0.5))
handle = bpy.context.object
handle.name = "DoorHandle"
handle_mat = bpy.data.materials.new(name="MetalMaterial")
handle_mat.use_nodes = True
handle_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.8, 0.8, 0.8, 1)
handle.data.materials.append(handle_mat)
# 创建窗户
window_width = 0.4
window_height = 0.4
bpy.ops.mesh.primitive_cube_add(size=1, location=(-0.68, 0.4, 1))
window = bpy.context.object
window.name = "Window"
window.scale = (window_width, window_width, window_height)
window_mat = bpy.data.materials.new(name="GlassMaterial")
window_mat.use_nodes = True
window_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (1.5, 1.5, 1.5, 0.3)
window_mat.specular_intensity = 0
# 创建窗台
bpy.ops.mesh.primitive_cube_add(size=1, location=(-0.9, 0.4, 0.8))
windowsill = bpy.context.object
windowsill.name = "Windowsill"
windowsill.scale = (0.1, 0.5, 0.02)
windowsill_mat = bpy.data.materials.new(name="DarkBrownMaterial")
windowsill_mat.use_nodes = True
windowsill_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.3, 0.15, 0, 1)
windowsill.data.materials.append(windowsill_mat)
# 创建屋顶
bpy.ops.mesh.primitive_cone_add(vertices=4, radius1=1.5, depth=0.9, location=(0, 0, 1.8))
roof = bpy.context.object
roof.name = "Roof"
roof_mat = bpy.data.materials.new(name="RedMaterial")
roof_mat.use_nodes = True
roof_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (1, 0, 0, 1)
roof.data.materials.append(roof_mat)
bpy.context.object.rotation_euler[2] = 0.78
# 创建烟囱
bpy.ops.mesh.primitive_cylinder_add(radius=0.2, depth=1, location=(0.5, 0.5, 1.7))
chimney = bpy.context.object
chimney.name = "Chimney"
chimney_mat = bpy.data.materials.new(name="GrayMaterial")
chimney_mat.use_nodes = True
chimney_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.5, 0.5, 0.5, 1)
chimney.data.materials.append(chimney_mat)
# 创建白球作为烟
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.09, location=(0.5, 0.5, 2.3))
smoke_ball = bpy.context.object
smoke_ball.name = "SmokeBall"
smoke_mat = bpy.data.materials.new(name="WhiteMaterial")
smoke_mat.use_nodes = True
smoke_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (1.5, 1.5, 1.5, 1.5)
smoke_ball.data.materials.append(smoke_mat)
# 设置关键帧动画让小球上升并消失再出现
initial_height = 2.0
final_height = 2.75
frame_interval = 100
def set_keyframes(frame, height):
smoke_ball.location[2] = height
smoke_ball.keyframe_insert(data_path="location", frame=frame)
for frame in range(1, 300):
cycle = frame // frame_interval
if frame % frame_interval < frame_interval // 2:
height = initial_height + ((final_height - initial_height) * (frame % frame_interval) / (frame_interval // 2))
set_keyframes(frame, height)
else:
if (frame % frame_interval) == frame_interval // 2:
set_keyframes(frame, initial_height)
height = initial_height + ((final_height - initial_height) * ((frame % frame_interval) - frame_interval // 2) / (frame_interval // 2))
set_keyframes(frame, height)
# 创建底座
bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, -0.1))
base = bpy.context.object
base.name = "Base"
base.scale = (1.8, 2, 0.2)
# 创建第一阶台阶
bpy.ops.mesh.primitive_cube_add(size=1, location=(-0.9, -0.4, -0.1))
step1 = bpy.context.object
step1.name = "Step1"
step1.scale = (0.3, 0.5, 0.2)
step1_mat = bpy.data.materials.new(name="StepMaterial")
step1_mat.use_nodes = True
step1_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.5, 0.5, 0.5, 1)
step1.data.materials.append(step1_mat)
# 创建第二阶台阶
bpy.ops.mesh.primitive_cube_add(size=1, location=(-1.05, -0.4, -0.15))
step2 = bpy.context.object
step2.name = "Step2"
step2.scale = (0.3, 0.5, 0.1)
step2_mat = bpy.data.materials.new(name="StepMaterial")
step2_mat.use_nodes = True
step2_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.5, 0.5, 0.5, 1)
step2.data.materials.append(step2_mat)
# 创建草坪
bpy.ops.mesh.primitive_plane_add(size=2, location=(0, 0, -0.2))
lawn = bpy.context.object
lawn.name = "Lawn"
lawn.scale = (3, 3, 1)
lawn_mat = bpy.data.materials.new(name="LawnMaterial")
lawn_mat.use_nodes = True
lawn_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0, 0.8, 0, 0.8)
lawn.data.materials.append(lawn_mat)
import bpy
import random
import math
def create_room():
# 删除所有物体,清空场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
bpy.data.collections["Collection"].name = "room"
# 创建蓝色材质
blue_material = bpy.data.materials.new(name="BlueMaterial")
blue_material.diffuse_color = (0, 0, 1, 1) # 蓝色 (R, G, B, Alpha)
# 创建椅子的座位
bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0.5))
seat = bpy.context.object
seat.scale.x = 0.5 # 椅面宽度
seat.scale.y = 0.5 # 椅面深度
seat.scale.z = 0.2 # 椅面厚度
seat.name = "Seat"
seat.data.materials.append(blue_material) # 应用蓝色材质
# 创建椅背
bpy.ops.mesh.primitive_cube_add(size=1, location=(0, -0.55, 1.5))
backrest = bpy.context.object
backrest.scale.x = 1.0 # 椅背宽度
backrest.scale.y = 0.3 # 椅背厚度
backrest.scale.z = 5 # 椅背高度
backrest.name = "Backrest"
backrest.data.materials.append(blue_material) # 应用蓝色材质
# 创建四条椅腿
leg_positions = [(-0.5, -0.5, -1.5), (-0.5, 0.5, -1.5), (0.5, -0.5, -1.5), (0.5, 0.5, -1.5)]
legs = []
for pos in leg_positions:
bpy.ops.mesh.primitive_cube_add(size=1, location=pos)
leg = bpy.context.object
leg.scale.x = 0.1 # 椅腿宽度
leg.scale.y = 0.1 # 椅腿厚度
leg.scale.z = 3.0 # 椅腿高度
leg.name = "Leg"
leg.data.materials.append(blue_material) # 应用蓝色材质
legs.append(leg)
# 设定父子关系,让椅子的各个部分成为整体
backrest.parent = seat
for leg in legs:
leg.parent = seat
### 创建浅粉色材质(用于桌子)
pink_material = bpy.data.materials.new(name="PinkMaterial")
pink_material.diffuse_color = (1, 0.75, 0.8, 1) # 浅粉色
### === 创建桌子=== ###
bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 1, 0.9))
table_top = bpy.context.object
table_top.scale.x = 1.5 # 桌面宽度
table_top.scale.y = 1.5 # 桌面深度
table_top.scale.z = 0.13 # 桌面厚度
table_top.name = "TableTop"
table_top.data.materials.append(pink_material)
# 桌腿(调整到桌子四角)
table_leg_positions = [(0.3,0.3,-3.2), (0.3,-0.3,-3.2), (-0.3,0.3,-3.2), (-0.3,-0.3,-3.2)]
table_legs = []
for pos in table_leg_positions:
bpy.ops.mesh.primitive_cylinder_add(radius=0.1, depth=7.2, location=pos)
table_leg = bpy.context.object
table_leg.name = "TableLeg"
table_leg.data.materials.append(pink_material)
table_legs.append(table_leg)
# 设定父子关系(绑定桌腿到桌面)
for leg in table_legs:
leg.parent = table_top
# 书的材质(红、绿、黄)
book_colors = [
(1, 0, 0, 1), # 红色
(0, 1, 0, 1), # 绿色
(1, 1, 0, 1) # 黄色
]
### === 在桌子上的书 === ###
num_books = random.randint(4, 6) # 随机
for i in range(num_books):
x_pos = -0.2 + random.uniform(0, 0.5) # 书的 X 位置
y_pos = 0.7 +random.uniform(-0.5, 0.5) # 书的 Y 位置
z_pos = 1 + (i * 0.05) # 书的 Z 位置
rotation = math.radians(random.uniform(-15, 15)) # 书的旋转角度
# 创建一本书(立方体)
bpy.ops.mesh.primitive_cube_add(size=1, location=(x_pos, y_pos, z_pos))
book = bpy.context.object
book.scale.x = random.uniform(0.3, 0.5) # 书的宽度
book.scale.y = random.uniform(0.2, 0.4) # 书的深度
book.scale.z = 0.05 # 书的厚度
book.rotation_euler.z = rotation # 旋转角度
book.name = f"Book_{i+1}"
# 随机选择颜色
book_material = bpy.data.materials.new(name=f"BookMaterial_{i+1}")
book_material.diffuse_color = random.choice(book_colors) # 书的颜色
book.data.materials.append(book_material)
### === 创建大理石地板 === ###
# 创建平面作为地板
bpy.ops.mesh.primitive_plane_add(size=2, location=(5, 2, -0.05))
floor = bpy.context.object
floor.name = "Floor"
floor.scale.x = 5
floor.scale.y = 5
# 创建大理石材质
marble_material = bpy.data.materials.new(name="MarbleMaterial")
marble_material.use_nodes = True # 启用节点
nodes = marble_material.node_tree.nodes
links = marble_material.node_tree.links
# 删除默认的节点
for node in nodes:
nodes.remove(node)
# 添加纹理节点
texture_node = nodes.new(type="ShaderNodeTexNoise")
texture_node.inputs["Scale"].default_value = 5
texture_node.inputs["Detail"].default_value = 16
texture_node.inputs["Distortion"].default_value = 1.5
# 添加漫反射着色器
diffuse_shader = nodes.new(type="ShaderNodeBsdfDiffuse")
diffuse_shader.location = (400, 0)
# 添加输出节点
output_node = nodes.new(type="ShaderNodeOutputMaterial")
output_node.location = (600, 0)
# 连接漫反射着色器到输出节点
links.new(diffuse_shader.outputs["BSDF"], output_node.inputs["Surface"])
# 应用大理石材质到地板
floor.data.materials.append(marble_material)
# 设定地板位置
floor.location = (0, 0, -0.05)
### === 创建花盆 === ###
bpy.ops.mesh.primitive_cylinder_add(radius=0.4, depth=0.5, location=(2, 0, 0.25))
pot = bpy.context.object
pot.name = "Pot"
# 花盆材质
pot_material = bpy.data.materials.new(name="PotMaterial")
pot_material.diffuse_color = (0.5, 0.25, 0.1, 1)
pot.data.materials.append(pot_material)
### === 创建土壤=== ###
bpy.ops.mesh.primitive_cylinder_add(radius=0.35, depth=0.1, location=(2, 0, 0.45))
soil = bpy.context.object
soil.name = "Soil"
# 土壤材质
soil_material = bpy.data.materials.new(name="SoilMaterial")
soil_material.diffuse_color = (0.3, 0.15, 0.1, 1)
soil.data.materials.append(soil_material)
### === 创建植物主干=== ###
bpy.ops.mesh.primitive_cylinder_add(radius=0.05, depth=0.6, location=(2, 0, 0.7))
trunk = bpy.context.object
trunk.name = "Trunk"
# 树干材质
trunk_material = bpy.data.materials.new(name="TrunkMaterial")
trunk_material.diffuse_color = (0.4, 0.2, 0.1, 1)
trunk.data.materials.append(trunk_material)
### === 创建叶片(随机分布)=== ###
leaf_material = bpy.data.materials.new(name="LeafMaterial")
leaf_material.diffuse_color = (0, 0.6, 0.2, 1)
num_leaves = 10 # 叶子数量
for i in range(num_leaves):
angle = random.uniform(0, 2 * math.pi) # 随机角度
radius = random.uniform(0.2, 0.4)
x_pos = 2 + radius * math.cos(angle)
y_pos = radius * math.sin(angle)
z_pos = random.uniform(0.8, 1.2) # 叶子高度
bpy.ops.mesh.primitive_plane_add(size=0.2, location=(x_pos, y_pos, z_pos))
leaf = bpy.context.object
leaf.name = f"Leaf_{i+1}"
leaf.rotation_euler.x = random.uniform(-0.5, 0.5)
leaf.rotation_euler.y = random.uniform(-0.5, 0.5)
leaf.rotation_euler.z = angle
leaf.data.materials.append(leaf_material)
### === 创建杯子 === ###
bpy.ops.mesh.primitive_cylinder_add(radius=0.15, depth=0.2, location=(-0.5, 0.5, 1.05))
cup = bpy.context.object
cup.name = "Cup"
# 杯子材质
cup_material = bpy.data.materials.new(name="CupMaterial")
cup_material.diffuse_color = (1, 1, 1, 1)
cup.data.materials.append(cup_material)
# 创建手柄
bpy.ops.mesh.primitive_torus_add(major_radius=0.08, minor_radius=0.02, location=(-0.65, 0.5, 1.05))
handle = bpy.context.object
handle.name = "CupHandle"
handle.rotation_euler.x = 1.57
# 应用相同材质
handle.data.materials.append(cup_material)
### === 创建台灯 === ###
# 底座
bpy.ops.mesh.primitive_cylinder_add(radius=0.2, depth=0.05, location=(-0.5, 1.5, 1))
lamp_base = bpy.context.object
lamp_base.name = "LampBase"
# 灯杆
bpy.ops.mesh.primitive_cylinder_add(radius=0.03, depth=0.3, location=(-0.5, 1.5, 1.1))
lamp_pole = bpy.context.object
lamp_pole.name = "LampPole"
# 灯罩
bpy.ops.mesh.primitive_cone_add(radius1=0.15, radius2=0.05, depth=0.2, location=(-0.5, 1.5, 1.3))
lamp_shade = bpy.context.object
lamp_shade.name = "LampShade"
# 颜色设置
lamp_material = bpy.data.materials.new(name="LampMaterial")
lamp_material.diffuse_color = (0.5, 0.5, 0.5, 1)
lamp_base.data.materials.append(lamp_material)
lamp_pole.data.materials.append(lamp_material)
lamp_shade_material = bpy.data.materials.new(name="LampShadeMaterial")
lamp_shade_material.diffuse_color = (1, 1, 0.6, 1)
lamp_shade.data.materials.append(lamp_shade_material)
### === 创建地毯 === ###
bpy.ops.mesh.primitive_plane_add(size=3, location=(0, 0.6, 0.01))
carpet = bpy.context.object
carpet.name = "Carpet"
# 地毯材质
carpet_material = bpy.data.materials.new(name="CarpetMaterial")
carpet_material.diffuse_color = (0.8, 0.2, 0.2, 1)
carpet.data.materials.append(carpet_material)
### === 创建散落的书页 === ###
for i in range(5):
x_pos = random.uniform(-0.9, 0.9)
y_pos = random.uniform(-0.5, 0.5)
z_pos = 0.02
bpy.ops.mesh.primitive_plane_add(size=0.25, location=(x_pos, y_pos, z_pos))
page = bpy.context.object
page.name = f"Paper_{i+1}"
page.rotation_euler.z = random.uniform(-1, 1)
page_material = bpy.data.materials.new(name=f"PaperMaterial_{i+1}")
page.data.materials.append(page_material)
# === 添加墙壁===
bpy.ops.mesh.primitive_plane_add(size=7.5, location=(2.8, 0.04, 3.5))
wall_right = bpy.context.object
wall_right.name = "RightWall"
wall_right.rotation_euler.y = 1.5708
# === 砖墙材质 ===
wall_texture = bpy.data.materials.new(name="BrickWall")
wall_texture.diffuse_color = (0.7, 0.6, 0.5, 1)
wall_right.data.materials.append(wall_texture)
# 创建对面墙
bpy.ops.mesh.primitive_cube_add(size=5, location=(0, 3.7, 3.5))
wall2 = bpy.context.object
wall2.name = "Wall_Opposite"
wall2.scale = (2, 0, 1.5)
wall_mat = bpy.data.materials.new(name="WallMat_Opposite")
wall_mat.use_nodes = True
wall_mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'].default_value = (0.7, 0.6, 0.5, 1.0)
wall2.data.materials.append(wall_mat)
# === 添加窗户 ===
bpy.ops.mesh.primitive_plane_add(size=3, location=(2.7, 1.5, 3))
window = bpy.context.object
window.name = "WallWindow"
window.rotation_euler.y = 1.5708
# 玻璃材质
window_material = bpy.data.materials.new(name="GlassMaterial")
window_material.diffuse_color = (1, 1, 1, 0.1)
window_material.blend_method = 'BLEND'
window.data.materials.append(window_material)
# === 添加小架子 ===
bpy.ops.mesh.primitive_cube_add(size=1, location=(2.7, -1, 2))
shelf = bpy.context.object
shelf.name = "WallShelf"
# 架子材质
shelf_material = bpy.data.materials.new(name="ShelfMaterial")
shelf_material.diffuse_color = (0.6, 0.3, 0.1, 1)
shelf.data.materials.append(shelf_material)
# === 在架子上增加多个小花盆 ===
num_pots = 3
pot_positions = [(-1.3, 2.55), (-1, 2.55), (-0.7, 2.55)]
for i, (x_offset, z_height) in enumerate(pot_positions):
bpy.ops.mesh.primitive_cylinder_add(radius=0.1, depth=0.15, location=(2.7, x_offset, z_height))
flower_pot = bpy.context.object
flower_pot.name = f"FlowerPot_{i}"
# 花盆材质
flower_pot_material = bpy.data.materials.new(name=f"PotMaterial_{i}")
flower_pot_material.diffuse_color = (0.6, 0.3, 0.2, 1)
flower_pot.data.materials.append(flower_pot_material)
# 生成随机方向的叶子
for j in range(random.randint(4, 6)):
bpy.ops.mesh.primitive_plane_add(size=0.08, location=(2.7 + random.uniform(-0.05, 0.05), x_offset, z_height + 0.1 + random.uniform(-0.02, 0.02)))
leaf = bpy.context.object
leaf.name = f"Leaf_{i}_{j}"
leaf.rotation_euler.x = random.uniform(0, 3.14)
# 叶子材质
leaf_material = bpy.data.materials.new(name=f"LeafMaterial_{i}")
leaf_material.diffuse_color = (0.1, 0.6, 0.1, 1)
leaf.data.materials.append(leaf_material)
# === 3.增强墙上的装饰画 ===
bpy.ops.mesh.primitive_plane_add(size=0.8, location=(2.7, -0.6, 3.5))
painting = bpy.context.object
painting.name = "WallPainting"
painting.rotation_euler.y = 1.5708
# 创建垃圾桶(一个简单的圆柱体)
bpy.ops.mesh.primitive_cylinder_add(radius=0.15, depth=0.3, location=(0.6, -0.3, 0.15))
trash_can = bpy.context.object
trash_can.name = "TrashCan"
mat_trash = bpy.data.materials.new(name="TrashMaterial")
mat_trash.diffuse_color = (0.2, 0.2, 0.2, 1)
trash_can.data.materials.append(mat_trash)
# 创建床架
bpy.ops.mesh.primitive_cube_add(size=1.5, location=(1, -2, 0))
bed_frame = bpy.context.object
bed_frame.scale.x = 2
bed_frame.scale.y = 1
bed_frame.scale.z = 0.5
bed_frame.name = "BedFrame"
# 创建床垫
bpy.ops.mesh.primitive_cube_add(size=1.5, location=(1, -2, 0.5))
mattress = bpy.context.object
mattress.scale.x = 1.9
mattress.scale.y = 0.9
mattress.scale.z = 0.2
mattress.name = "Mattress"
# 给床垫加颜色(淡蓝色)
mat_mattress = bpy.data.materials.new(name="MattressMaterial")
mat_mattress.diffuse_color = (0.6, 0.7, 1, 1) # RGBA格式
mattress.data.materials.append(mat_mattress)
# 创建枕头
bpy.ops.mesh.primitive_cube_add(size=1.5, location=(2, -2, 0.8))
pillow = bpy.context.object
pillow.scale.x = 0.6
pillow.scale.y = 0.3
pillow.scale.z = 0.1
pillow.name = "Pillow"
pillow.rotation_euler.z = math.radians(90)
# 给枕头加颜色(白色)
mat_pillow = bpy.data.materials.new(name="PillowMaterial")
mat_pillow.diffuse_color = (1, 1, 1, 1)
pillow.data.materials.append(mat_pillow)
create_room()import bpy
import random
def clear_scene():
"""清除场景中所有对象"""
if bpy.context.active_object and bpy.context.active_object.mode != 'OBJECT':
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
def create_material(name, color, is_glass=False, is_emission=False, is_door=False):
"""创建材质,兼容 Blender 4.0+"""
mat = bpy.data.materials.new(name=name)
mat.use_nodes = True
bsdf = mat.node_tree.nodes["Principled BSDF"]
bsdf.inputs["Base Color"].default_value = color
if is_glass:
bsdf.inputs["Roughness"].default_value = 0.1
if "Transmission Weight" in bsdf.inputs:
bsdf.inputs["Transmission Weight"].default_value = 0.9
elif "Transmission" in bsdf.inputs:
bsdf.inputs["Transmission"].default_value = 0.9
elif is_emission:
if "Emission Color" in bsdf.inputs:
bsdf.inputs["Emission Color"].default_value = color
bsdf.inputs["Emission Strength"].default_value = 5.0
elif "Emission" in bsdf.inputs:
bsdf.inputs["Emission"].default_value = color
elif is_door:
bsdf.inputs["Roughness"].default_value = 0.4
bsdf.inputs["Metallic"].default_value = 0.2
else:
bsdf.inputs["Roughness"].default_value = 0.6
return mat
def create_building(location, size, floors, materials):
"""
创建一个简单的楼房
location: (x, y, z) 楼房底部中心坐标
size: (width, depth, height)
floors: 层数
materials: 材质字典
"""
x, y, z = location
width, depth, height = size
# 1. 创建楼体
bpy.ops.mesh.primitive_cube_add(size=1, location=(x, y, z + height / 2))
building = bpy.context.active_object
building.name = "Building"
building.scale = (width, depth, height)
if building.data.materials:
building.data.materials[0] = materials['wall']
else:
building.data.materials.append(materials['wall'])
# 2. 创建窗户和大门
window_h = (height / floors) * 0.6
window_w = 1.5
window_d = 0.1
floor_h = height / floors
num_windows = int(width / 2.5)
if num_windows < 1: num_windows = 1
start_x = x - (width / 2) + (width / (num_windows + 1))
step_x = width / (num_windows + 1)
# 大门参数
door_w = 3.0 # 大门比窗户宽
door_h = 3.5 # 大门比窗户高
door_d = 0.15
# 计算中间窗户的索引,用于放置大门
center_idx = num_windows // 2
for f in range(floors):
win_z = z + (f + 0.5) * floor_h
for w in range(num_windows):
win_x = start_x + w * step_x
# --- 前墙 (南面) ---
# 如果是底层且是中间位置,创建大门,否则创建窗户
if f == 0 and w == center_idx:
# 创建大门
bpy.ops.mesh.primitive_cube_add(size=1, location=(win_x, y - depth/2 - door_d/2, z + door_h/2))
door = bpy.context.active_object
door.name = f"Main_Door"
door.scale = (door_w, door_d, door_h)
door.data.materials.append(materials['door'])
door.parent = building
door.matrix_parent_inverse = building.matrix_world.inverted()
# 创建从大门通向主路的连接道路
# 假设主路在 y = -5 附近
create_road((win_x, y - depth/2), (win_x, -5), 2.5, materials)
else:
# 前墙窗户
bpy.ops.mesh.primitive_cube_add(size=1, location=(win_x, y - depth/2 - window_d/2, win_z))
win_front = bpy.context.active_object
win_front.name = f"Window_Front_{f}_{w}"
win_front.scale = (window_w, window_d, window_h)
win_front.data.materials.append(materials['glass'])
win_front.parent = building
win_front.matrix_parent_inverse = building.matrix_world.inverted()
# --- 后墙 (北面) ---
# 后墙只放窗户
bpy.ops.mesh.primitive_cube_add(size=1, location=(win_x, y + depth/2 + window_d/2, win_z))
win_back = bpy.context.active_object
win_back.name = f"Window_Back_{f}_{w}"
win_back.scale = (window_w, window_d, window_h)
win_back.data.materials.append(materials['glass'])
win_back.parent = building
win_back.matrix_parent_inverse = building.matrix_world.inverted()
def create_road(start, end, width, materials):
"""创建一个简单的道路"""
x1, y1 = start
x2, y2 = end
length = ((x2 - x1)**2 + (y2 - y1)**2)**0.5
cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
angle = 0
if x2 != x1:
import math
angle = math.atan((y2 - y1) / (x2 - x1))
elif y2 != y1: # 垂直道路
import math
angle = math.pi / 2
bpy.ops.mesh.primitive_plane_add(size=1, location=(cx, cy, 0.01))
road = bpy.context.active_object
road.name = "Road"
road.scale = (length, width, 1)
road.rotation_euler = (0, 0, angle)
if road.data.materials:
road.data.materials[0] = materials['road']
else:
road.data.materials.append(materials['road'])
def create_tree(location, materials):
"""创建一棵简单的树"""
x, y, z = location
scale = random.uniform(0.8, 1.2)
# 树干
bpy.ops.mesh.primitive_cylinder_add(radius=0.2 * scale, depth=2 * scale, location=(x, y, z + 1 * scale))
trunk = bpy.context.active_object
trunk.name = "Tree_Trunk"
trunk.data.materials.append(materials['trunk'])
# 树冠
bpy.ops.mesh.primitive_ico_sphere_add(radius=1.2 * scale, location=(x, y, z + 2.5 * scale))
leaves = bpy.context.active_object
leaves.name = "Tree_Leaves"
leaves.data.materials.append(materials['leaves'])
# 组合
leaves.parent = trunk
leaves.matrix_parent_inverse = trunk.matrix_world.inverted()
def create_flower(location, materials):
"""创建一个简单的花"""
x, y, z = location
# 随机颜色:从红色到黄色再到绿色之间随机
r = random.uniform(0.0, 1.0)
g = random.uniform(0.0, 1.0)
b = 0.1
if r < 0.3: r += 0.5
if g < 0.2: g += 0.2
color = (r, g, b, 1.0)
mat_name = f"Flower_Mat_{random.randint(0, 1000)}"
mat = bpy.data.materials.new(name=mat_name)
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs["Base Color"].default_value = color
bpy.ops.mesh.primitive_ico_sphere_add(radius=0.15, location=(x, y, z + 0.15))
flower = bpy.context.active_object
flower.name = "Flower"
flower.data.materials.append(mat)
def create_boundary_wall(min_x, max_x, min_y, max_y, height, materials):
"""创建四周的围墙"""
thickness = 0.5
# 北墙 (y = max_y)
width = max_x - min_x
bpy.ops.mesh.primitive_cube_add(size=1, location=((min_x + max_x)/2, max_y, height/2))
wall_n = bpy.context.active_object
wall_n.name = "Wall_North"
wall_n.scale = (width + thickness, thickness, height)
wall_n.data.materials.append(materials['wall_boundary'])
# 南墙 (y = min_y) - 留个门
gate_width = 8
width_part = (width - gate_width) / 2
# 左半部分
bpy.ops.mesh.primitive_cube_add(size=1, location=(min_x + width_part/2, min_y, height/2))
wall_s1 = bpy.context.active_object
wall_s1.name = "Wall_South_1"
wall_s1.scale = (width_part, thickness, height)
wall_s1.data.materials.append(materials['wall_boundary'])
# 右半部分
bpy.ops.mesh.primitive_cube_add(size=1, location=(max_x - width_part/2, min_y, height/2))
wall_s2 = bpy.context.active_object
wall_s2.name = "Wall_South_2"
wall_s2.scale = (width_part, thickness, height)
wall_s2.data.materials.append(materials['wall_boundary'])
# 东墙 (x = max_x)
depth = max_y - min_y
bpy.ops.mesh.primitive_cube_add(size=1, location=(max_x, (min_y + max_y)/2, height/2))
wall_e = bpy.context.active_object
wall_e.name = "Wall_East"
wall_e.scale = (thickness, depth + thickness, height)
wall_e.data.materials.append(materials['wall_boundary'])
# 西墙 (x = min_x)
bpy.ops.mesh.primitive_cube_add(size=1, location=(min_x, (min_y + max_y)/2, height/2))
wall_w = bpy.context.active_object
wall_w.name = "Wall_West"
wall_w.scale = (thickness, depth + thickness, height)
wall_w.data.materials.append(materials['wall_boundary'])
def create_visible_sun(location, radius, materials):
"""创建一个可见的太阳球体"""
bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, location=location)
sun_sphere = bpy.context.active_object
sun_sphere.name = "Visible_Sun"
sun_sphere.data.materials.append(materials['sun'])
def main():
clear_scene()
# 准备材质
mats = {
'wall': create_material("Wall_Mat", (0.8, 0.75, 0.7, 1.0)),
'wall_boundary': create_material("Wall_Boundary_Mat", (0.7, 0.7, 0.7, 1.0)),
'glass': create_material("Glass_Mat", (0.4, 0.6, 0.9, 1.0), is_glass=True),
'door': create_material("Door_Mat", (0.3, 0.2, 0.1, 1.0), is_door=True),
'ground': create_material("Ground_Mat", (0.2, 0.5, 0.2, 1.0)),
'road': create_material("Road_Mat", (0.3, 0.3, 0.3, 1.0)),
'trunk': create_material("Trunk_Mat", (0.4, 0.2, 0.1, 1.0)),
'leaves': create_material("Leaves_Mat", (0.1, 0.4, 0.1, 1.0)),
'sun': create_material("Sun_Mat", (1.0, 0.9, 0.5, 1.0), is_emission=True)
}
# 创建地面
bpy.ops.mesh.primitive_plane_add(size=100, location=(0, 0, 0))
ground = bpy.context.active_object
ground.name = "Ground"
ground.data.materials.append(mats['ground'])
# 创建楼房
create_building((0, 0, 0), (12, 8, 15), 4, mats) # 主楼
create_building((-20, 10, 0), (10, 6, 9), 3, mats) # 副楼1
create_building((20, 10, 0), (10, 6, 9), 3, mats) # 副楼2
# 创建道路
create_road((-30, -5), (30, -5), 4, mats) # 东西向主路
create_road((0, -5), (0, -25), 4, mats) # 南向通往围墙大门的主路
# 创建围墙
create_boundary_wall(-40, 40, -25, 25, 3, mats)
# 创建树木和花朵
# 1. 东西向主路 (y=-5) 两侧
road_y = -5
road_width = 4
# 北侧树木 (避开主楼)
for x in range(-35, 36, 6):
if abs(x) < 8: continue # 避开主楼前区域
create_tree((x, road_y + road_width/2 + 2, 0), mats)
for _ in range(3):
fx = x + (random.random() - 0.5) * 3
fy = road_y + road_width/2 + 2 + (random.random() - 0.5) * 3
create_flower((fx, fy, 0), mats)
# 南侧树木 (避开大门路口)
for x in range(-35, 36, 6):
if abs(x) < 4: continue # 避开大门路口
create_tree((x, road_y - road_width/2 - 2, 0), mats)
for _ in range(3):
fx = x + (random.random() - 0.5) * 3
fy = road_y - road_width/2 - 2 + (random.random() - 0.5) * 3
create_flower((fx, fy, 0), mats)
# 2. 南向主路 (x=0, y 从 -5 到 -25) 两侧
# 这条路是连接主楼和围墙大门的大路
central_road_x = 0
central_road_width = 4
for y in range(-22, -6, 6): # 从大门附近往北种
# 东侧
create_tree((central_road_x + central_road_width/2 + 2, y, 0), mats)
for _ in range(3):
fx = central_road_x + central_road_width/2 + 2 + (random.random() - 0.5) * 3
fy = y + (random.random() - 0.5) * 3
create_flower((fx, fy, 0), mats)
# 西侧
create_tree((central_road_x - central_road_width/2 - 2, y, 0), mats)
for _ in range(3):
fx = central_road_x - central_road_width/2 - 2 + (random.random() - 0.5) * 3
fy = y + (random.random() - 0.5) * 3
create_flower((fx, fy, 0), mats)
# 草地上随机撒花 (在空旷区域)
for _ in range(50):
fx = random.uniform(-35, 35)
fy = random.uniform(-20, 20)
if abs(fy - road_y) > 5 and abs(fx) > 10:
create_flower((fx, fy, 0), mats)
# 添加灯光和可见太阳
sun_loc = (10, -10, 20)
bpy.ops.object.light_add(type='SUN', location=sun_loc)
sun = bpy.context.active_object
sun.data.energy = 5
sun.rotation_euler = (0.5, 0, 0.8)
create_visible_sun(sun_loc, 2.0, mats)
print("✅ 场景生成完成:主干道两侧均已种植树木")
# 保存文件
output_path = "/tmp/result.blend"
bpy.ops.wm.save_as_mainfile(filepath=output_path)
print(f"✅ 文件已保存至: {output_path}")
if __name__ == "__main__":
main()
import bpy
import math
import random
def create_material(name, color):
mat = bpy.data.materials.new(name=name)
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (*color, 1)
return mat
# 创建立方体的函数(支持角度输入)
def create_cube(name, location, rotation_deg, scale, material=None):
bpy.ops.mesh.primitive_cube_add(location=location, size=2) # 添加立方体
obj = bpy.context.object
obj.name = name
obj.scale = scale # 设置缩放比例
# 将角度转换为弧度
rotation_rad = (math.radians(rotation_deg[0]), math.radians(rotation_deg[1]), math.radians(rotation_deg[2]))
# 设置旋转角度
obj.rotation_euler = rotation_rad
if material:
obj.data.materials.append(material) # 如果有材质,则附加材质
return obj
def create_sphere(name, location, scale, material=None):
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=location)
obj = bpy.context.object
obj.name = name
obj.scale = scale
if material:
obj.data.materials.append(material)
return obj
def create_cone(name, location, rotation_deg,scale, material=None):
bpy.ops.mesh.primitive_cone_add(radius1=1, depth=2, location=location)
obj = bpy.context.object
obj.name = name
obj.scale = scale
rotation_rad = (math.radians(rotation_deg[0]), math.radians(rotation_deg[1]), math.radians(rotation_deg[2]))
obj.rotation_euler = rotation_rad
if material:
obj.data.materials.append(material)
return obj
def create_cylinder(name, location, rotation_deg, scale, material=None):
bpy.ops.mesh.primitive_cylinder_add(radius=1, depth=2, location=location)
obj = bpy.context.object
obj.name = name
obj.scale = scale
# 将角度转换为弧度
rotation_rad = (math.radians(rotation_deg[0]), math.radians(rotation_deg[1]), math.radians(rotation_deg[2]))
# 设置旋转角度
obj.rotation_euler = rotation_rad
if material:
obj.data.materials.append(material)
return obj
# 创建环形体(Torus)的函数
def create_torus(name, location, major_radius, minor_radius, scale, material=None):
bpy.ops.mesh.primitive_torus_add(location=location, major_radius=major_radius, minor_radius=minor_radius) # 添加环形体
obj = bpy.context.object
obj.name = name
obj.scale = scale
if material:
obj.data.materials.append(material) # 如果有材质,则附加材质
return obj
# 创建日光
def add_sun_light():
# 添加一个光源,类型为 "SUN"
bpy.ops.object.light_add(type='SUN', location=(0, 0, 10)) # 位置可以调整
sun = bpy.context.object
sun.name = "SunLight"
# 设置光源强度(光的能量)
sun.data.energy = 2.5 # 设置光源的强度,数值可以调整
# 设置光源颜色
sun.data.color = (1, 1, 0.8) # 近似黄色的光
# 设置光源的方向
sun.rotation_euler = (math.radians(45), math.radians(0), math.radians(45)) # 设置光照角度,模拟太阳的位置
def create_girl():
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
skin_mat = create_material("Skin", (1, 0.8, 0.6))
eye_white_mat = create_material("EyeWhite", (1, 1, 1))
eye_black_mat = create_material("EyeBlack", (0, 0, 0))
cloth_mat = create_material("Cloth", (1, 0.5, 0))
headband_mat = create_material("Headband", (0, 0, 0.8))
head = create_sphere("Head", (0, 0, 1.56), (0.3, 0.3, 0.3), skin_mat)
left_eye = create_sphere("LeftEye", (-0.243953, -0.133555, 1.62303), (0.055,0.055,0.055), eye_white_mat)
right_eye = create_sphere("RightEye", (-0.243953, 0.133555, 1.62303), (0.055,0.055,0.055), eye_white_mat)
left_pupil = create_sphere("LeftPupil", (-0.3, -0.133555, 1.62303), (0.02,0.02,0.02), eye_black_mat)
right_pupil = create_sphere("RightPupil",(-0.3, 0.133555, 1.62303), (0.02,0.02,0.02), eye_black_mat)
nose = create_cube("Nose", (-0.262794, 0, 1.52), (0,12,0), (0.059, 0.02, 0.059), skin_mat)
headband = create_sphere("Headband", (0, 0, 1.85), (0.3, 0.3, 0.106), headband_mat)
body = create_cone("Body", (0, 0, 1),(0,0,0) ,(0.418, 0.418, 0.418), cloth_mat)
left_arm = create_cylinder("LeftArm", (0, -0.32, 1.2), (-127, 0, 0), (0.072, 0.072, 0.26), skin_mat)
right_arm = create_cylinder("RightArm", (0, 0.328, 1), (73, 0, 0), (0.072, 0.072,0.26), skin_mat)
left_hand = create_sphere("LeftHand",(-0.002476, -0.558189, 1.38772), (0.1, 0.1, 0.1), skin_mat)
right_hand = create_sphere("RightHand",(-0.002476, 0.610417, 0.914956), (0.1, 0.1, 0.1), skin_mat)
left_leg = create_cylinder("LeftLeg", (0, -0.1, 0.38441), (0, 0, 0), (0.072, 0.072, 0.26), skin_mat)
right_leg = create_cylinder("RightLeg", (0, 0.1, 0.38441), (0, 0, 0), (0.072, 0.072,0.26), skin_mat)
left_foot = create_sphere("LeftFoot",(0, -0.1, 0.089822), (0.1, 0.1, 0.1), skin_mat)
right_foot = create_sphere("RightFoot",(0, 0.1, 0.089822), (0.1, 0.1, 0.1), skin_mat)
girl = bpy.data.objects.new("Girl", None)
bpy.context.collection.objects.link(girl)
for obj in [head, left_eye, right_eye, left_pupil, right_pupil, nose,
headband, body, left_arm, right_arm, left_hand, right_hand, left_leg,
right_leg, left_foot, right_foot]:
obj.parent = girl
print("Girl created successfully!")
def create_snowman():
snow_mat = create_material("Snow", (1, 1, 1))
eye_black_mat = create_material("EyeBlack",(0,0,0))
hat_mat = create_material("Hat",(1,0,0))
nose_mat = create_material("Nose",(1,0.2,0))
arm_mat = create_material("Arm",(0.9,0.4,0))
head = create_sphere("Head", (0,1.3141,1),(0.278,0.278,0.278),snow_mat)
body = create_sphere("Body",(0,1.3141,0.4),(0.4,0.4,0.4),snow_mat)
left_eye = create_sphere("LeftEye",(-0.213425 ,1.2213,1.0916),(0.042,0.042,0.042),eye_black_mat)
right_eye = create_sphere("RightEye",(-0.213425 ,1.40547,1.0916),(0.042,0.042,0.042),eye_black_mat)
hat = create_cone("Hat",(0,1.3141,1.3831),(0,0,0),(0.21,0.21,0.21),hat_mat)
hat_ball = create_sphere("HatBall",(0,1.3141,1.5811),(0.072,0.072,0.072),snow_mat)
nose = create_cone("Nose",(-0.33468,1.3141,0.97731),(0,-90,0),(0.045,0.045,0.135),nose_mat)
scarf = create_torus("Scarf",(0,1.3141,0.78305),1,0.25,(0.215,0.215,0.215), hat_mat)
shawl = create_cube("Shawl",(0.21787,0.926674,0.517964),(-43.1032,0,28.6661),(0.139,0.02,0.383),hat_mat)
left_arm = create_cylinder("LeftArm",(0,0.895892,0.679607),(43.2376,0,0),(0.031,0.031,0.249),arm_mat)
right_arm = create_cylinder("RightArm",(0,1.7517,0.679607),(-43.2376,0,0),(0.031,0.031,0.249),arm_mat)
left_hand = create_sphere("LeftHand",(0,0.71859,0.86714),(0.06,0.06,0.06),snow_mat)
right_hand = create_sphere("RightHand",(0,1.93773,0.86714),(0.06,0.06,0.06),snow_mat)
snowman = bpy.data.objects.new("Snowman", None)
bpy.context.collection.objects.link(snowman)
for obj in [head, left_eye, right_eye, hat,hat_ball, nose, scarf, shawl,
body, left_arm, right_arm, left_hand, right_hand]:
obj.parent = snowman
def create_house():
wall_mat = create_material("Wall",(0.6,0.6,0.6))
wood_mat = create_material("Wood",(0.9,0.4,0))
roof_mat = create_material("Roof",(0.8,0.8,0.1))
wall = create_cube("Wall",(-6.15605 ,4.35755 ,2.83782 ),(0,0,-25),(2.936,2.936,2.936),wall_mat)
roof = create_cone("Roof",(-6.15605,4.3576,7.5574),(0,0,0),(5,5,2),roof_mat)
door = create_cube("Door",(-3.1506,3.6743,1.2088),(0,0,-25),(0.043,0.732,1.252),wood_mat)
window = create_cube("Window",(-4.0674,1.9061,4.1483),(0,0,-25),(0.079,0.8,0.59),wood_mat)
def create_tree(num_trees=10, radius=5, inner_radius=2, seed=42):
random.seed(seed) # 设置随机种子,确保每次生成的树位置一致
trunk_mat = create_material("TreeTrunkMaterial", (0.6, 0.3, 0.1)) # 树干材质(棕色)
tree_mat = create_material("TreeMaterial", (0.1, 0.5, 0.1)) # 树冠材质(绿色)
for i in range(num_trees):
# 随机决定树的大小
tree_size = random.choice(["small", "medium", "large"])
# 使用随机种子计算树的位置
while True:
angle = random.uniform(0, 2 * math.pi) # 随机生成角度
r = random.uniform(0, radius) # 随机生成半径
x = r * math.cos(angle) # 极坐标转笛卡尔坐标
y = r * math.sin(angle) # 极坐标转笛卡尔坐标
z = 0 # 高度保持在雪地上
# 检查是否位于排除的区域内
if r >= inner_radius: # 如果树的位置距离中心至少是 inner_radius,继续生成
break # 退出循环,开始生成树
# 树干(圆柱)
trunk_height = random.uniform(1, 3)
bpy.ops.mesh.primitive_cylinder_add(radius=0.2, depth=trunk_height, location=(x, y, z + trunk_height / 2))
trunk = bpy.context.object
trunk.name = "TreeTrunk"
trunk.data.materials.append(trunk_mat)
# 树冠(圆锥)
if tree_size == "small":
# 小树只有一个圆锥
bpy.ops.mesh.primitive_cone_add(vertices=20, radius1=1, radius2=0, depth=2, location=(x, y, z + trunk_height + 1))
tree_top = bpy.context.object
tree_top.name = "TreeTop"
tree_top.scale = (0.8, 0.8, 1)
elif tree_size == "medium":
# 中树有两个圆锥
# 下部圆锥
bpy.ops.mesh.primitive_cone_add(vertices=20, radius1=1.5, radius2=0, depth=2, location=(x, y, z + trunk_height+1))
tree_top1 = bpy.context.object
tree_top1.name = "TreeTop1"
# 上部圆锥
bpy.ops.mesh.primitive_cone_add(vertices=20, radius1=1, radius2=0, depth=1.5, location=(x, y, z + trunk_height +2))
tree_top2 = bpy.context.object
tree_top2.name = "TreeTop2"
tree_top2.scale = (0.7, 0.7, 1)
elif tree_size == "large":
# 大树有三个圆锥
# 下部圆锥
bpy.ops.mesh.primitive_cone_add(vertices=20, radius1=1.8, radius2=0, depth=3, location=(x, y, z + trunk_height + 1))
tree_top1 = bpy.context.object
tree_top1.name = "TreeTop1"
# 中部圆锥
bpy.ops.mesh.primitive_cone_add(vertices=20, radius1=1.5, radius2=0, depth=2, location=(x, y, z + trunk_height + 2))
tree_top2 = bpy.context.object
tree_top2.name = "TreeTop2"
tree_top2.scale = (0.8, 0.8, 1)
# 上部圆锥
bpy.ops.mesh.primitive_cone_add(vertices=20, radius1=1, radius2=0, depth=1.5, location=(x, y, z + trunk_height + 3))
tree_top3 = bpy.context.object
tree_top3.name = "TreeTop3"
tree_top3.scale = (0.6, 0.6, 1)
if tree_size == "small":
tree_top.data.materials.append(tree_mat)
elif tree_size == "medium":
tree_top1.data.materials.append(tree_mat)
tree_top2.data.materials.append(tree_mat)
elif tree_size == "large":
tree_top1.data.materials.append(tree_mat)
tree_top2.data.materials.append(tree_mat)
tree_top3.data.materials.append(tree_mat)
def create_env():
snow_mat = create_material("SnowPlane",(1,1,1))
snow_plane = create_cylinder("SnowPlane",(0,0,-0.1),(0,0,0),(12,12,0.1),snow_mat)
create_girl()
create_snowman()
create_house()
create_tree(30,11,5,2)
create_env()
add_sun_light()
import bpy
import math
import random
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
def create_material(name, color):
mat = bpy.data.materials.new(name=name)
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (*color, 1)
return mat
def create_duck(location):
body_mat = create_material("DuckBody", (1, 1, 0)) # 黄色材质
beak_mat = create_material("DuckBeak", (1, 0.6, 0)) # 橙色材质
wing_mat = create_material("DuckWing", (0.8, 0.8, 0)) # 黄绿色材质
eye_mat = create_material("DuckEye", (0, 0, 0)) # 黑色眼睛材质
# 鸭子的身体(使用球体代替)
body = create_sphere("DuckBody", location, (0.3, 0.3, 0.2), body_mat) # 球体作为鸭子的身体
body.location = location # 设置位置
# 鸭子的头部(使用球体代替)
head = create_sphere("DuckHead", (location[0], location[1], location[2] + 0.2), (0.2, 0.2, 0.2), body_mat)
# 鸭子的嘴巴(使用球体代替,缩小)
beak = create_sphere("DuckBeak", (location[0], location[1] + 0.1, location[2] + 0.35), (0.1, 0.05, 0.05), beak_mat)
# 鸭子的翅膀(使用球体代替)
wing_left = create_sphere("DuckWingLeft", (location[0] - 0.15, location[1], location[2] + 0.05), (0.2, 0.05, 0.15), wing_mat)
wing_right = create_sphere("DuckWingRight", (location[0] + 0.15, location[1], location[2] + 0.05), (0.2, 0.05, 0.15), wing_mat)
# 鸭子的尾巴(使用小球体代替)
tail = create_sphere("DuckTail", (location[0], location[1]-0.3, location[2]-0.05), (0.1, 0.1, 0.05), body_mat)
# 鸭子的眼睛(两个小球体)
eye_left = create_sphere("DuckEyeLeft", (location[0] - 0.06, location[1] - 0.05, location[2] + 0.37), (0.03, 0.05, 0.03), eye_mat)
eye_right = create_sphere("DuckEyeRight", (location[0] + 0.06, location[1] - 0.05, location[2] + 0.37), (0.03, 0.05, 0.03), eye_mat)
return [body, head, beak, wing_left, wing_right, tail, eye_left, eye_right]
def create_bear(location):
body_mat = create_material("BearBody", (0.4, 0.2, 0.1)) # 棕色身体
head_mat = create_material("BearHead", (0.6, 0.3, 0.1)) # 浅棕色头部
eye_mat = create_material("BearEye", (0, 0, 0)) # 黑色眼睛
paw_mat = create_material("BearPaw", (0.3, 0.1, 0)) # 深棕色的爪子
# 熊的身体
body = create_sphere("BearBody", location, (0.6, 0.5, 0.8), body_mat) # 身体使用球体表示
# 熊的头部
head = create_sphere("BearHead", (location[0], location[1], location[2] + 1), (0.4, 0.4, 0.4), head_mat)
# 熊的耳朵
ear_left = create_sphere("BearEarLeft", (location[0] - 0.2, location[1] + 0.1, location[2] + 1.35), (0.1, 0.1, 0.1), head_mat)
ear_right = create_sphere("BearEarRight", (location[0] + 0.2, location[1] + 0.1, location[2] + 1.35), (0.1, 0.1, 0.1), head_mat)
# 熊的眼睛(使用小球体表示)
eye_left = create_sphere("BearEyeLeft", (location[0] - 0.08, location[1] + 0.3, location[2] + 1.2), (0.05, 0.05, 0.05), eye_mat)
eye_right = create_sphere("BearEyeRight", (location[0] + 0.08, location[1] + 0.3, location[2] + 1.2), (0.05, 0.05, 0.05), eye_mat)
nose = create_sphere("BearNose", (location[0], location[1] + 0.4, location[2] + 1), (0.1, 0.05, 0.07), head_mat)
# 熊的爪子(使用小球体)
paw_left = create_sphere("BearPawLeft", (location[0] - 0.4, location[1] +0.4, location[2] + 0.4), (0.12, 0.12, 0.12), paw_mat)
paw_right = create_sphere("BearPawRight", (location[0] + 0.4, location[1] +0.4, location[2] + 0.4), (0.12, 0.12, 0.12), paw_mat)
return [body, head, ear_left, ear_right, eye_left, eye_right, nose, paw_left, paw_right]
def create_sphere(name, location, scale, material=None):
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=location)
obj = bpy.context.object
obj.name = name
obj.scale = scale
if material:
obj.data.materials.append(material)
return obj
def create_cone(name, location, rotation_deg,scale, material=None):
bpy.ops.mesh.primitive_cone_add(radius1=1, depth=2, location=location)
obj = bpy.context.object
obj.name = name
obj.scale = scale
rotation_rad = (math.radians(rotation_deg[0]), math.radians(rotation_deg[1]), math.radians(rotation_deg[2]))
obj.rotation_euler = rotation_rad
if material:
obj.data.materials.append(material)
return obj
def create_cylinder(name, location, rotation_deg, scale, material=None):
bpy.ops.mesh.primitive_cylinder_add(radius=1, depth=2, location=location)
obj = bpy.context.object
obj.name = name
obj.scale = scale
# 将角度转换为弧度
rotation_rad = (math.radians(rotation_deg[0]), math.radians(rotation_deg[1]), math.radians(rotation_deg[2]))
# 设置旋转角度
obj.rotation_euler = rotation_rad
if material:
obj.data.materials.append(material)
return obj
# 创建日光
def add_sun_light():
# 添加一个光源,类型为 "SUN"
bpy.ops.object.light_add(type='SUN', location=(0, 0, 15)) # 位置可以调整
sun = bpy.context.object
sun.name = "SunLight"
# 设置光源强度(光的能量)
sun.data.energy = 1.5 # 设置光源的强度,数值可以调整
# 设置光源颜色
sun.data.color = (0.5, 0.5, 1) # 近似黄色的光
# 设置光源的方向
sun.rotation_euler = (math.radians(0), math.radians(45), math.radians(45)) # 设置光照角度,模拟太阳的位置
def create_tree(num_trees=10, radius=5, inner_radius=2, seed=42):
random.seed(seed) # 设置随机种子
trunk_mat = create_material("TreeTrunkMaterial", (0.6, 0.3, 0.1))
tree_mat = create_material("TreeMaterial", (0.1, 0.5, 0.1))
for i in range(num_trees):
# 随机决定树的大小
tree_size = random.choice(["small"])
# 使用随机种子计算树的位置
while True:
angle = random.uniform(0, 2 * math.pi)
r = random.uniform(0, radius)
x = r * math.cos(angle)
y = r * math.sin(angle)
z = -0.3
# 检查是否位于排除的区域内
if r >= inner_radius: # 如果树的位置距离中心至少是 inner_radius,继续生成
break # 退出循环,开始生成树
# 树干)
trunk_height = random.uniform(1, 3)
bpy.ops.mesh.primitive_cylinder_add(radius=0.2, depth=trunk_height, location=(x, y, z + trunk_height / 2))
trunk = bpy.context.object
trunk.name = "TreeTrunk"
trunk.data.materials.append(trunk_mat)
# 树冠
if tree_size == "small":
bpy.ops.mesh.primitive_cone_add(vertices=20, radius1=1, radius2=0, depth=2, location=(x, y, z + trunk_height + 1))
tree_top = bpy.context.object
tree_top.name = "TreeTop"
tree_top.scale = (0.8, 0.8, 1)
if tree_size == "small":
tree_top.data.materials.append(tree_mat)
# 创建池子
def create_pool(radius, depth, water_height):
water_mat = create_material("Water", (0.1, 0.4, 0.7))
pool_mat = create_material("Pool", (0.5, 0.5, 0.5))
# 创建池底
bpy.ops.mesh.primitive_cylinder_add(radius=radius, depth=depth, location=(0, 0, -depth / 2))
pool = bpy.context.object
pool.name = "PoolBottom"
pool.data.materials.append(pool_mat)
# 创建水面
bpy.ops.mesh.primitive_cylinder_add(radius=radius - 0.2, depth=water_height, location=(0, 0, water_height / 2))
water = bpy.context.object
water.name = "WaterSurface"
water.data.materials.append(water_mat)
return pool, water
# 创建环境
def create_env():
plane_mat = create_material("Plane", (0.3, 0.8, 0.3))
plane = create_cylinder("Plane", (0, 0, -0.2), (0, 0, 0), (10, 10, 0.1), plane_mat)
# 创建场景
def create_scene():
create_env()
create_tree(5,7,6,9)
# 创建池子
pool, water = create_pool(radius=5, depth=0.5, water_height=0.05)
# 创建鸭子
create_duck((0,-2,0.1))
# 创建熊
create_bear((0, -5.5, 0.5))
# 添加阳光
add_sun_light()
# 生成场景
create_scene()
import bpy
import math
import random
from mathutils import Vector
# 清除现有场景
def clear_scene():
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# 创建亭子
def create_pavilion(location=(0, 0, 0)):
# 亭子底座
bpy.ops.mesh.primitive_cylinder_add(
vertices=8, radius=3, depth=0.5,
location=(location[0], location[2], location[2] + 0.25)
)
base = bpy.context.object
base.name = "Pavilion_Base"
mat = bpy.data.materials.new(name="Base_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.7, 0.3, 0.1, 1.0)
base.data.materials.append(mat)
# 亭子柱子
for i in range(8):
angle = math.pi * 2 * i / 8
x = math.cos(angle) * 2
y = math.sin(angle) * 2
bpy.ops.mesh.primitive_cylinder_add(
vertices=8, radius=0.2, depth=3,
location=(location[0] + x, location[2] + y, location[2] + 2)
)
column = bpy.context.object
column.name = f"Pavilion_Column_{i}"
mat = bpy.data.materials.new(name="Column_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.5, 0.1, 0.1, 1.0)
column.data.materials.append(mat)
# 亭子顶部
bpy.ops.mesh.primitive_cone_add(
vertices=8, radius1=3.5, radius2=0, depth=3,
location=(location[0], location[2], location[2] + 4.5)
)
roof = bpy.context.object
roof.name = "Pavilion_Roof"
mat = bpy.data.materials.new(name="Roof_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.7, 0.3, 0.1, 1.0)
roof.data.materials.append(mat)
# 亭子顶部装饰
bpy.ops.mesh.primitive_uv_sphere_add(
radius=0.3, location=(location[0], location[2], location[2] + 6)
)
decoration = bpy.context.object
decoration.name = "Pavilion_Decoration"
mat = bpy.data.materials.new(name="Decoration_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.7, 0.3, 0.1, 1.0)
decoration.data.materials.append(mat)
# 将所有部分组合
bpy.ops.object.select_all(action='DESELECT')
for obj in bpy.data.objects:
if obj.name.startswith("Pavilion"):
obj.select_set(True)
bpy.context.view_layer.objects.active = base
bpy.ops.object.join()
base.name = "Suzhou_Pavilion"
# 创建树木
def create_tree(location=(0, 0, 0)):
# 树干
bpy.ops.mesh.primitive_cylinder_add(
vertices=8, radius=0.3, depth=3,
location=(location[0], location[1], location[2] + 1.5)
)
trunk = bpy.context.object
trunk.name = "Tree_Trunk"
mat = bpy.data.materials.new(name="Trunks_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.6, 0.4, 0.2, 1)
trunk.data.materials.append(mat)
# 树冠 - 多层球体叠加
for i in range(3):
size = 2 - i * 0.5
height = 3 + i * 1.2
bpy.ops.mesh.primitive_uv_sphere_add(
radius=size,
location=(location[0], location[1], location[2] + height),
segments=8, ring_count=6
)
leaves = bpy.context.object
leaves.name = f"Tree_Leaves_{i}"
mat = bpy.data.materials.new(name="Leaves_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.2, 0.6, 0.3, 1)
leaves.data.materials.append(mat)
# 将所有部分组合
bpy.ops.object.select_all(action='DESELECT')
for obj in bpy.data.objects:
if obj.name.startswith("Tree"):
obj.select_set(True)
bpy.context.view_layer.objects.active = trunk
bpy.ops.object.join()
trunk.name = "Suzhou_Tree"
# 创建草丛
def create_grass_patch(location=(0, 0, 0), count=10):
bpy.ops.object.select_all(action='DESELECT')
# 创建多个草叶
for i in range(count):
x = location[0] + random.uniform(-2, 2)
y = location[1] + random.uniform(-2, 2)
z = location[2]
# 草叶 - 使用细长的立方体
bpy.ops.mesh.primitive_cube_add(
size=1,
location=(x, y, z + 0.5)
)
grass = bpy.context.object
grass.name = f"Grass_{i}"
mat = bpy.data.materials.new(name="Grass_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.2, 0.6, 0.3, 1)
grass.data.materials.append(mat)
# 缩放和旋转草叶
grass.scale = (0.05, 0.05, random.uniform(0.3, 0.8))
grass.rotation_euler = (
random.uniform(-0.2, 0.2),
random.uniform(-0.2, 0.2),
random.uniform(0, math.pi * 2)
)
# 将所有草叶组合
bpy.ops.object.select_all(action='DESELECT')
for obj in bpy.data.objects:
if obj.name.startswith("Grass"):
obj.select_set(True)
if bpy.context.selected_objects:
bpy.context.view_layer.objects.active = bpy.context.selected_objects[0]
bpy.ops.object.join()
bpy.context.object.name = "Suzhou_Grass_Patch"
# 创建假山
def create_rock(location=(0, 0, 0)):
# 使用多个变形球体创建假山
bpy.ops.object.select_all(action='DESELECT')
for i in range(5):
x = location[0] + random.uniform(-1, 1)
y = location[1] + random.uniform(-1, 1)
z = location[2] + random.uniform(0, 0.5)
bpy.ops.mesh.primitive_uv_sphere_add(
radius=random.uniform(0.5, 1.5),
location=(x, y, z),
segments=8, ring_count=6
)
rock_part = bpy.context.object
rock_part.name = f"Rock_Part_{i}"
mat = bpy.data.materials.new(name="Rock_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.3, 0.3, 0.3, 1)
rock_part.data.materials.append(mat)
# 随机缩放和旋转
rock_part.scale = (
random.uniform(0.8, 1.2),
random.uniform(0.8, 1.2),
random.uniform(0.8, 1.5)
)
rock_part.rotation_euler = (
random.uniform(0, math.pi / 4),
random.uniform(0, math.pi / 4),
random.uniform(0, math.pi / 4)
)
# 将所有部分组合
bpy.ops.object.select_all(action='DESELECT')
for obj in bpy.data.objects:
if obj.name.startswith("Rock_Part"):
obj.select_set(True)
if bpy.context.selected_objects:
bpy.context.view_layer.objects.active = bpy.context.selected_objects[0]
bpy.ops.object.join()
bpy.context.object.name = "Suzhou_Rock"
# 创建湖
def create_lake(location=(0, 0, 0), size=6):
# 湖面 - 使用扁平圆柱体
bpy.ops.mesh.primitive_cylinder_add(
vertices=32, radius=size, depth=0.1,
location=(location[0], location[1], location[2] - 0.05)
)
lake = bpy.context.object
lake.name = "Suzhou_Lake"
mat = bpy.data.materials.new(name="Lake_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.1, 0.3, 0.8, 1)
lake.data.materials.append(mat)
# 创建桥
def create_bridge(location=(0, 0, 0), length=5):
# 桥面
bpy.ops.mesh.primitive_cube_add(
size=2.7,
location=(location[0], location[1], location[2] + 0.5)
)
bpy.context.object.scale=(length, 1, 0.1)
bridge_deck = bpy.context.object
bridge_deck.name = "Bridge_Deck"
mat = bpy.data.materials.new(name="Deck_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.4, 0.4, 0.4, 1)
bridge_deck.data.materials.append(mat)
# 桥栏杆
for side in [-1, 1]:
for i in range(int(length * 2.7) + 1):
x = location[0] + i - length - 2
y = location[1] + side
bpy.ops.mesh.primitive_cylinder_add(
vertices=6, radius=0.05, depth=1,
location=(x, y, location[2] + 0.8)
)
railing_post = bpy.context.object
railing_post.name = f"Bridge_Railing_Post_{side}_{i}"
mat = bpy.data.materials.new(name="Railing_Post_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.4, 0.4, 0.4, 1)
railing_post.data.materials.append(mat)
# 连接栏杆
bpy.ops.mesh.primitive_cube_add(
size=2.7,
location=(location[0], location[1] + side, location[2] + 0.8)
)
bpy.context.object.scale=(length, 0.05, 0.05)
railing_beam = bpy.context.object
railing_beam.name = f"Bridge_Railing_Beam_{side}"
mat = bpy.data.materials.new(name="Railing_Beam_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.4, 0.4, 0.4, 1)
railing_beam.data.materials.append(mat)
# 将所有部分组合
bpy.ops.object.select_all(action='DESELECT')
for obj in bpy.data.objects:
if obj.name.startswith("Bridge"):
obj.select_set(True)
bpy.context.view_layer.objects.active = bridge_deck
bpy.ops.object.join()
bridge_deck.name = "Suzhou_Bridge"
# 设置全景摄像机
def setup_panorama_camera():
# 计算场景边界(根据园林布局调整)
min_x, max_x = -25, 25
min_y, max_y = -25, 25
center = ((min_x + max_x) / 2, (min_y + max_y) / 2, 0)
# 动态计算摄像机参数
scene_size = max(max_x - min_x, max_y - min_y)
camera_height = scene_size * 0.8
orbit_radius = scene_size * 1.5 # 摄像机轨道半径
# 删除旧摄像机(避免冲突)
for obj in bpy.data.objects:
if obj.type == 'CAMERA':
bpy.data.objects.remove(obj, do_unlink=True)
# 创建焦点空物体
bpy.ops.object.empty_add(location=center)
focus = bpy.context.object
focus.name = "Camera_Focus"
# 设置动画范围
bpy.context.scene.frame_start = 1
bpy.context.scene.frame_end = 250
# 创建初始摄像机位置(设置在X轴和Y轴中间位置)
initial_angle = math.pi / 4 # 45度角,位于X和Y轴中间
cam_x = center[0] + math.cos(initial_angle) * orbit_radius
cam_y = center[1] + math.sin(initial_angle) * orbit_radius
bpy.ops.object.camera_add(
location=(cam_x, cam_y, camera_height),
rotation=(math.pi / 3, 0, initial_angle + math.pi / 2) # 60度俯角
)
camera = bpy.context.object
camera.name = "Panorama_Camera"
# 摄像机参数设置
camera.data.type = 'PERSP'
camera.data.lens = 35 # 35mm广角
camera.data.clip_start = 0.1
camera.data.clip_end = 500
# 添加追踪约束
track = camera.constraints.new('TRACK_TO')
track.target = focus
track.track_axis = 'TRACK_NEGATIVE_Z'
track.up_axis = 'UP_Y'
# 设为活动摄像机
bpy.context.scene.camera = camera
# 创建动画
if not camera.animation_data:
camera.animation_data_create()
# 清除旧的关键帧(如果有)
if camera.animation_data.action:
for fcurve in camera.animation_data.action.fcurves:
camera.animation_data.action.fcurves.remove(fcurve)
# 设置关键帧动画 - 让摄像机围绕中心点旋转
for frame in [1, 125, 250]:
# 计算当前角度(从初始角度开始旋转)
progress = (frame - 1) / (250 - 1)
angle = initial_angle + 2 * math.pi * progress
# 更新摄像机位置
camera.location.x = center[0] + math.cos(angle) * orbit_radius
camera.location.y = center[1] + math.sin(angle) * orbit_radius
camera.location.z = camera_height
# 插入关键帧
camera.keyframe_insert(data_path="location", frame=frame)
# 强制刷新动画系统
bpy.context.view_layer.update()
print(f"已创建摄像机动画:初始位置在X/Y轴中间,将在{orbit_radius}半径的轨道上围绕中心旋转")
return camera
# 创建整个苏州园林场景
def create_suzhou_garden():
clear_scene()
# 创建地面
bpy.ops.mesh.primitive_plane_add(size=1000, location=(0, 0, -0.1))
ground = bpy.context.object
ground.name = "Ground"
# 设置地面材质为绿色
mat = bpy.data.materials.new(name="Ground_Material")
mat.use_nodes = True
mat.node_tree.nodes["Principled BSDF"].inputs['Base Color'].default_value = (0.2, 0.6, 0.3, 1)
ground.data.materials.append(mat)
# 创建湖
create_lake(location=(5, 2, 0), size=8)
# 创建桥
create_bridge(location=(5, 0, 0.2), length=6)
# 创建亭子
create_pavilion(location=(-5.5, -5, 0))
create_pavilion(location=(15.5, 5, 0))
# 创建树木
for i in range(10):
x = random.uniform(-20, 20)
y = random.uniform(-20, 20)
if math.sqrt((x - 5) ** 2 + y ** 2) > 10:
create_tree(location=(x, y, 0))
# 创建草丛
for i in range(15):
x = random.uniform(-20, 20)
y = random.uniform(-20, 20)
if math.sqrt((x - 5) ** 2 + y ** 2) > 10:
create_grass_patch(location=(x, y, 0), count=random.randint(5, 15))
# 创建假山
create_rock(location=(12, -8, 0))
create_rock(location=(-8, 10, 0))
create_rock(location=(-10, -12, 0))
# 设置全景摄像机
setup_panorama_camera()
# 设置光源
bpy.ops.object.light_add(type='SUN', location=(10, -10, 20))
light = bpy.context.object
light.name = "Sun_Light"
light.data.energy = 2.0
light.data.angle = math.radians(5) # 使用light变量
# 添加补光
bpy.ops.object.light_add(type='AREA', location=(0, 0, 20))
fill = bpy.context.object
fill.name = "Fill_Light"
fill.data.energy = 500
fill.data.size = 30
# 渲染设置
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.render.resolution_x = 3840
bpy.context.scene.render.resolution_y = 2160
bpy.context.scene.render.fps = 24
bpy.context.scene.render.image_settings.file_format = 'FFMPEG'
bpy.context.scene.render.ffmpeg.format = 'MPEG4'
bpy.context.scene.render.ffmpeg.codec = 'H264'
bpy.context.scene.render.filepath = "//panorama_animation.mp4"
# 执行创建场景
create_suzhou_garden()
# 自动跳转到起始帧并播放
bpy.context.scene.frame_set(1)
bpy.ops.screen.animation_play()
-
这次我们看了
- 器物
- 场景
-
三维建模就像按照图纸施工
- 图纸这种东西怎么来的呢?
- 我们下次再说!👋
- 本文来自 oeasy Python 系统教程。
- 想完整、扎实学 Python,
- 搜索 oeasy 即可。






















