Error in user YAML: (<unknown>): did not find expected key while parsing a block mapping at line 1 column 1
---
show: step
version: 1.0
enable_checker: true
- 本教程同步发布在:
- 个人网站: `https://oeasy.org`
- 蓝桥云课: `https://www.lanqiao.cn/courses/3584`
- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial`
- Gitee: `https://gitee.com/overmind1980/oeasypython`
---- oeasy Python 0682
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
-
上次 研究了 旋转函数
- rotation_euler 旋转
-
xyz 三个轴向的旋转值构成一个列表
- rotation_ruler[0] 是 x轴
- rotation_ruler[1] 是 y轴
- rotation_ruler[2] 是 z轴
-
如果一个 造型 做出来了
- 想让他以一个整体的方式 旋转 该怎么办呢?
-
如果我想得到乘号
- 应该如何修改代码呢?
import bpy
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物体
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.rotation_euler[1] = 1.5708
- 将 两个立方体
- 沿 y 轴
- 分别旋转角度 90°、270°
import bpy
import math
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物体
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.rotation_euler[1] = math.pi / 4
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.rotation_euler[1] = math.pi / 4 * 3
- 两个立柱
- 各自旋转
- 确实 得到一个乘号
- 但是 这个乘号 是分两次 旋转过来的
- 而不是 从加号 一次旋转 过来的
- 我想要 先做出 加号
- 然后 再旋转
整个加号 - 可以吗?
- 然后 再旋转
- 先回到起点
- 新建一个blender文件
- 尝试得到加号
import bpy
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物体
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.rotation_euler[1] = 1.5708
- 执行代码后
- 任务完成
- 怎么把他们变成
一个对象?
- 场景数据视图中
- 有两个对象
- 选中Cube.001对象
- 观察底部 状态栏
-
整个Collection中
- 顶点(Verticles) 16个
- 面(Faces) 12个
- 三角形(Triangles) 24个
- 物体(Objects) 2个
-
选中的是 2个 物体中的 1个
- Cube.001
- 先选择 Cube
- 再 shift 加选择 Cube.001
- 注意 先选择的 更明亮、鲜艳一些
bpy.context.selected_objects
bpy.context.active_object
bpy.context.object
- 在游乐场中运行
- 选中的对象
- 有两个
- 活跃的对象
- 有一个
- 设置他们之间的关系
- 点击3D视图的菜单
- Object 对象
- Parent 父母
- Object对象
- Cube.001(先选的) 就成为
- Cube(后选的) 的一部分
- 算是 Cube的 儿子 了
- 尝试旋转父级对象
-
旋转父亲
- 儿子跟着转
-
这对应什么代码呢?
- 观察 信息面板
- 有这么一句
bpy.ops.object.parent_set(type='OBJECT')
- 想要纯代码完成 应该如何呢?
- phind给的例子 非常到位!!!
import bpy
# Get references to the objects
parent_obj = bpy.data.objects['Cube']
child_obj = bpy.data.objects['Cube.001']
# Set the parent-child relationship
child_obj.parent = parent_obj
- 总共分成两步
- 首先 得到 对象
- 然后 设置 关系
- 分三步
- 清空场景
- 生成+号
- 设置父子关系
import bpy
import math
# clear current scene
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物体
# create objects
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.rotation_euler[1] = math.pi / 2
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
# set parent
parent_obj = bpy.data.objects['Cube']
child_obj = bpy.data.objects['Cube.001']
child_obj.parent = parent_obj
- 结果如图
- 好像变长了
- 两个立方体重合了
- 这怎么理解?
- Cube 在 y轴 旋转了 90°
- 所以立方体 竖了起来
- 再看Cube.001
- Cube.001 在
- y轴 没有旋转
- 在x轴 3倍缩放
- 但由于Cube.001是儿子
- 跟随着父亲Cube
- 旋转了 90度
- 就竖过来了
- 又由于父级
- 在x轴 3倍缩放
- 里外里 x轴 翻了3*3倍
- 9倍
- 跟随着父亲Cube
- 那怎么解决?
- 最后旋转子对象
- 清场景
- 创建对象
- 先设置父子关系
- 后将子对象旋转
import bpy
import math
# clear current scene
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物体
# create objects
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
# set parent
parent_obj = bpy.data.objects['Cube']
child_obj = bpy.data.objects['Cube.001']
child_obj.parent = parent_obj
# 将子对象 旋转
child_obj.rotation_euler[1] = math.pi / 2
- 运行结果
- 父亲正确
- 儿子 变胖?
- Cube 旋转 缩放都ok
- 虽然是后设置的父子关系
- 但是一旦设置父子关系后
- 子对象的缩放、旋转
- 都受到父对象的影响
- Cube.001
- 由于 成为了 儿子
- 导致 y轴 缩放为原来的 3倍
- 于是 成了 扁平方块
- 刚才那个立方体
- 高度 过高
- 也是同样道理
- 因为
- 翻了3倍
- 又翻3倍
- 三三见九倍
- 问题是 想要 纯代码实现
- 十字架 并且 统一旋转
- 两个方块 彼此之间
- 互不影响
- 互为兄弟
- 两兄弟
- 跟着 一个父亲
- 父亲 带着
- 两个子对象
- 一拖二
- 如何建立父亲对象呢?
- 封装了函数
- 调用函数
- 取其精华
import bpy
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物体
empty_obj = bpy.data.objects.new("empty", None)
empty_obj.name = "Parent"
bpy.data.collections["Collection"].objects.link(empty_obj)
- 打开文件
- Run Script
- 真的出了一个 Parent
- 在此基础上融合之前代码
import bpy
import math
# clear current scene
bpy.ops.object.select_all(action="SELECT") # 选择所有物体
bpy.ops.object.delete() # 删除选定的物体
# create objects
empty_obj = bpy.data.objects.new("empty", None)
empty_obj.name = "Parent"
bpy.data.collections["Collection"].objects.link(empty_obj)
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.parent = empty_obj
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.rotation_euler[1] = math.pi / 2
bpy.context.object.parent = empty_obj
- 只要再旋转 空对象
- 就行了
- 选中parent
- 尝试旋转
- 应该是沿着 y 轴
- rotation_ruler[1]
empty_obj.rotation_euler[1] = math.pi / 4
- 将 空对象 旋转
- 90°
- 合 π/4
- 得到乘号
- 结构是这样的
- 所有的都放在Collection里面
- 有一个空对象 Parent 作为容器
- 里面两个 Cube 对象
- 每个对象里面 一个 Mesh
- 父亲
- 名字清晰
- 可以让
两兄弟的名字- 更加明确吗?
import bpy
import math
# clear current scene
bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()
# create objects
empty_obj = bpy.data.objects.new("empty", None)
empty_obj.name = "Parent"
bpy.data.collections["Collection"].objects.link(empty_obj)
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.parent = empty_obj
bpy.context.object.name = "elder_brother"
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.scale[0] = 3
bpy.context.object.rotation_euler[1] = math.pi / 2
bpy.context.object.parent = empty_obj
bpy.context.object.name = "younger_brother"
empty_obj.rotation_euler[1] = math.pi / 4
- 运行结果
- 这次名字也完美了
-
这次研究了父子关系
- 父亲旋转 儿子跟着
- 可以通过设置parent控制父子关系
-
可以 新建一个 空对象 None
- 作为 抽象的虚拟爸爸
- 然后 将 各种对象放入其中
- 虚拟爸爸👨 可以控制很多儿子👦👦👦
- 可以做出这样的交叉体吗?🤔
- 我们下次再说!👋
- 配套视频
- 本文来自 oeasy Python 系统教程。
- 想完整、扎实学 Python,
- 搜索 oeasy 即可。





























