blender 2.8 python,使用二分法将对象分成两半会产生错误的结果
blender 2.8 python, dividing object in 2 halfs using bisect is producing wrong result
我使用 Blender 2.8 创建了一个复杂的对象,我想将其拆分为两个单独的对象。
我遵循的过程(所有脚本):创建对象;重复对象;进入编辑模式并用“'clear_inner=True'”平分。 (工作完美!)
然后 select 其他(原始)对象;进入编辑模式并用“'clear_outer=True'”平分。
现在第一个对象似乎也受到平分:只有一些 points/faces 是平分的。
我包含了一个简单立方体的代码:
import bpy
bpy.ops.mesh.primitive_cube_add(size=4, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.name="left"
bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'})
bpy.context.object.name="right"
# cutting in two (bisect)
bpy.data.objects['left'].select_set(False)
bpy.data.objects['right'].select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 28.5249, 5.80484), plane_no=(1, 0, 0), use_fill=True, clear_inner=True, threshold=0.0001, xstart=1042, xend=1068, ystart=647, yend=130)
bpy.ops.object.editmode_toggle()
bpy.data.objects['right'].select_set(False)
bpy.data.objects['left'].select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 28.5249, 5.80484), plane_no=(1, 0, 0), use_fill=True, clear_outer=True, threshold=0.0001, xstart=1042, xend=1068, ystart=647, yend=130)
bpy.ops.object.editmode_toggle()
using bisect to seperate cube in two halfs
在图片中您看到第二个平分的结果成功地将第一个立方体减半 ('left')。但它也分裂了复制的立方体('right'),它已经被减半,只在平分平面上产生一个面。
为什么不起作用?我究竟做错了什么?
问题是由第二个 bpy.ops.mesh.select_all(action='SELECT')
引起的。 None 是必需的,因为在您更改它之前会选择整个网格。这会导致选择两个立方体的网格,然后对它们进行平分。这是可能的,因为 Blender 2.80 允许您一次编辑多个对象。问题的根源是select_set(False)
。这将取消选择对象,但不会更改其活动状态。当您切换第二个多维数据集的编辑模式时,您正在编辑两者,因为一个被选中并且第二个处于活动状态。您可以通过删除代码的最后 3 行来尝试,您将看到发生了什么。您必须通过设置 bpy.context.view_layer.objects.active
来更改它,如第二个代码所示。
此外,您不需要填写 bpy.ops.mesh.bisect
函数的所有参数,并且 plane_co
是切割平面上的点,我认为它应该为零,但这取决于您。
文档:https://docs.blender.org/api/current/bpy.ops.mesh.html?highlight=mesh#bpy.ops.mesh.bisect
使用 bpy.ops.object.select_all(action='DESELECT')
编辑代码:
...
# deselect all objects
bpy.ops.object.select_all(action='DESELECT')
# select just right object
bpy.data.objects['right'].select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.bisect(plane_co=(0, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_inner=True)
bpy.ops.object.editmode_toggle()
# deselect all objects
bpy.ops.object.select_all(action='DESELECT')
# select just left object
bpy.data.objects['left'].select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.bisect(plane_co=(0, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_outer=True)
bpy.ops.object.editmode_toggle()
这个也有效 - 使用 bpy.context.view_layer.objects.active
:
...
bpy.data.objects['left'].select_set(False)
bpy.data.objects['right'].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects['right'] # set right as active
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_inner=True)
bpy.ops.object.editmode_toggle()
bpy.data.objects['right'].select_set(False)
bpy.data.objects['left'].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects['left'] # set left as active
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_outer=True)
bpy.ops.object.editmode_toggle()
我使用 Blender 2.8 创建了一个复杂的对象,我想将其拆分为两个单独的对象。
我遵循的过程(所有脚本):创建对象;重复对象;进入编辑模式并用“'clear_inner=True'”平分。 (工作完美!) 然后 select 其他(原始)对象;进入编辑模式并用“'clear_outer=True'”平分。 现在第一个对象似乎也受到平分:只有一些 points/faces 是平分的。
我包含了一个简单立方体的代码:
import bpy
bpy.ops.mesh.primitive_cube_add(size=4, enter_editmode=False, location=(0, 0, 0))
bpy.context.object.name="left"
bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":False, "mode":'TRANSLATION'})
bpy.context.object.name="right"
# cutting in two (bisect)
bpy.data.objects['left'].select_set(False)
bpy.data.objects['right'].select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 28.5249, 5.80484), plane_no=(1, 0, 0), use_fill=True, clear_inner=True, threshold=0.0001, xstart=1042, xend=1068, ystart=647, yend=130)
bpy.ops.object.editmode_toggle()
bpy.data.objects['right'].select_set(False)
bpy.data.objects['left'].select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 28.5249, 5.80484), plane_no=(1, 0, 0), use_fill=True, clear_outer=True, threshold=0.0001, xstart=1042, xend=1068, ystart=647, yend=130)
bpy.ops.object.editmode_toggle()
using bisect to seperate cube in two halfs
在图片中您看到第二个平分的结果成功地将第一个立方体减半 ('left')。但它也分裂了复制的立方体('right'),它已经被减半,只在平分平面上产生一个面。
为什么不起作用?我究竟做错了什么?
问题是由第二个 bpy.ops.mesh.select_all(action='SELECT')
引起的。 None 是必需的,因为在您更改它之前会选择整个网格。这会导致选择两个立方体的网格,然后对它们进行平分。这是可能的,因为 Blender 2.80 允许您一次编辑多个对象。问题的根源是select_set(False)
。这将取消选择对象,但不会更改其活动状态。当您切换第二个多维数据集的编辑模式时,您正在编辑两者,因为一个被选中并且第二个处于活动状态。您可以通过删除代码的最后 3 行来尝试,您将看到发生了什么。您必须通过设置 bpy.context.view_layer.objects.active
来更改它,如第二个代码所示。
此外,您不需要填写 bpy.ops.mesh.bisect
函数的所有参数,并且 plane_co
是切割平面上的点,我认为它应该为零,但这取决于您。
文档:https://docs.blender.org/api/current/bpy.ops.mesh.html?highlight=mesh#bpy.ops.mesh.bisect
使用 bpy.ops.object.select_all(action='DESELECT')
编辑代码:
...
# deselect all objects
bpy.ops.object.select_all(action='DESELECT')
# select just right object
bpy.data.objects['right'].select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.bisect(plane_co=(0, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_inner=True)
bpy.ops.object.editmode_toggle()
# deselect all objects
bpy.ops.object.select_all(action='DESELECT')
# select just left object
bpy.data.objects['left'].select_set(True)
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.bisect(plane_co=(0, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_outer=True)
bpy.ops.object.editmode_toggle()
这个也有效 - 使用 bpy.context.view_layer.objects.active
:
...
bpy.data.objects['left'].select_set(False)
bpy.data.objects['right'].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects['right'] # set right as active
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_inner=True)
bpy.ops.object.editmode_toggle()
bpy.data.objects['right'].select_set(False)
bpy.data.objects['left'].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects['left'] # set left as active
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(0, 0, 0), plane_no=(1, 0, 0), use_fill=True, clear_outer=True)
bpy.ops.object.editmode_toggle()