Error in user YAML: (<unknown>): found a tab character that violate indentation while scanning a plain scalar at line 3 column 3
---
- oeasy Python 0735
- 这是 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`
---import bpy
import bmesh
from math import radians, cos, sin
data_list = [bpy.data.meshes, bpy.data.materials]
for i in range(len(data_list)):
list = data_list[i].values()
for j in range(len(list)):
data_list[i].remove(list[j])
def set_material(obj):
mat = bpy.data.materials.new('material')
obj.data.materials.append(mat)
mat.use_nodes = True
if 'Principled BSDF' in mat.node_tree.nodes:
shader_Principled_BSDF = mat.node_tree.nodes['Principled BSDF']
else:
shader_Principled_BSDF = mat.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
if shader_Principled_BSDF is None:
print("Error: Could not create or find Principled BSDF node")
return
shader_Principled_BSDF.location = (500, 0)
output = mat.node_tree.nodes.get('Material Output')
if output is None:
print("Error: Could not find Material Output node")
return
output.location = (800, 0)
attribute = mat.node_tree.nodes.new('ShaderNodeAttribute')
attribute.location = (0, 0)
attribute.attribute_name = 'vert_color'
color_ramp = mat.node_tree.nodes.new('ShaderNodeValToRGB')
color_ramp.location = (200, 0)
color_ramp.color_ramp.elements[0].color = (1.0, 0.0, 0.0, 1.0)
color_ramp.color_ramp.elements[1].color = (0.0, 1.0, 0.0, 1.0)
link = mat.node_tree.links.new
link(attribute.outputs[0], color_ramp.inputs[0])
link(color_ramp.outputs[0], shader_Principled_BSDF.inputs[0])
link(shader_Principled_BSDF.outputs[0], output.inputs[0])
# 插入颜色变化关键帧
for frame in range(0, 401, 20):
color_ramp.color_ramp.elements[0].color = (1.0, frame / 400.0, 0.0, 1.0)
color_ramp.color_ramp.elements[1].color = (0.0, 1.0 - frame / 400.0, 0.0, 1.0)
color_ramp.color_ramp.elements[0].keyframe_insert(data_path="color", frame=frame)
color_ramp.color_ramp.elements[1].keyframe_insert(data_path="color", frame=frame)
radius = 0.015
depth = 1
vertices = 6
bpy.ops.mesh.primitive_cylinder_add(vertices=vertices, radius=radius, depth=depth,
location=(0, depth*cos(radians(30)), 0), rotation=(0, radians(90), 0))
unit = bpy.context.active_object
bpy.ops.object.shade_smooth()
bpy.ops.object.transform_apply(rotation=True)
bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(unit.data)
color_layer = bm.verts.layers.color.new('vert_color')
for vert in bm.verts:
vert[color_layer] = (vert.co.x/depth+0.5, 0.0, 0.0, 1.0)
bmesh.update_edit_mesh(unit.data)
bm.free()
bpy.ops.object.mode_set(mode='OBJECT')
set_material(unit)
unit.select_set(True)
for i in range(5):
bpy.ops.object.duplicate_move_linked()
duplicate = bpy.context.object
duplicate.rotation_euler[2] = radians(60)*(i+1)
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.join()
hexagon = bpy.context.active_object
hexagon.name = 'hexagon'
bpy.ops.object.transform_apply()
hexagon.select_set(True)
hexagons = []
theta = 10
for i in range(20):
bpy.ops.object.duplicate_move_linked()
duplicate = bpy.context.object
hexagons.append(duplicate)
duplicate.rotation_euler[2] += radians(theta)
duplicate.scale *= sin(radians(60))/sin(radians(120-theta))
for i, obj in enumerate(hexagons):
frame_start = 1
frame_step = 20 # 将步长加倍
for f in range(theta):
frame_end = frame_start + frame_step
obj.keyframe_insert('rotation_euler', frame=frame_start)
obj.keyframe_insert('scale', frame=frame_start)
obj.animation_data.action.fcurves[0].extrapolation = 'LINEAR'
obj.rotation_euler[2] -= radians(1)*(i+1)
s = pow(sin(radians(60))/sin(radians(120-theta+f+1)), i+1)
obj.scale = (s, s, s)
obj.keyframe_insert('rotation_euler', frame=frame_end)
obj.keyframe_insert('scale', frame=frame_end)
obj.animation_data.action.fcurves[0].extrapolation = 'LINEAR'
frame_start = frame_end
frame_step *= 1.15
bpy.context.scene.frame_end = 400
bpy.context.scene.render.fps = 60
bpy.ops.object.camera_add(location=(0, 0, 4))
camera = bpy.context.object
camera.keyframe_insert(data_path="location", frame=1)
camera.location = (0, 0, 8)
camera.keyframe_insert(data_path="location", frame=200)
camera.location = (0, 0, 4)
camera.keyframe_insert(data_path="location", frame=400)
bpy.context.scene.camera = camera
- 清理数据为了确保场景干净,我们首先清理Blender中现有的网格和材质数据。这有助于避免任何旧数据干扰新的动画创建。
- . 设置材质为六边形设置材质,使其在动画过程中能够展示颜色变化。我们使用Blender的节点系统来创建和配置材质,并插入颜色变化的关键帧。
- 创建六边形单元创建一个六边形单元,并为其设置平滑阴影和顶点颜色。然后将其复制并旋转,形成一个完整的六边形。
-
- 创建旋转动画通过复制和旋转六边形,创建一个旋转动画。每个复制的六边形在动画过程中都会缩放和旋转,形成一个动态的视觉效果。
-
- 设置摄像头动画为了更好地展示六边形的旋转动画,我们需要创建一个摄像头,并设置摄像头的动画,使其在场景中移动。摄像头将从远处开始,逐渐靠近六边形,然后再返回原位。
- 本文来自 oeasy Python 系统教程。
- 想完整、扎实学 Python,
- 搜索 oeasy 即可。