3

使用 Blender 2.8,我创建了一个复杂的对象,我想将其拆分为两个单独的对象。

我遵循的过程(所有脚本):创建对象;重复对象;进入编辑模式并用 '''clear_inner=True''' 平分。(完美!)然后选择其他(原始)对象;进入编辑模式并用 '''clear_outer=True''' 平分。现在第一个对象似乎也受到了二等分:只有一些点/面被二等分保留。

我包括一个简单多维数据集的代码:

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()

使用 bisect 将立方体分成两半

在图片中,您看到第二个二等分的结果成功地将第一个立方体(“左”)减半。但它也分裂了已经被减半的复制立方体('right'),导致只在平分平面上产生一个面。

为什么它不起作用?我究竟做错了什么?

4

1 回答 1

1

问题是由第二个引起的bpy.ops.mesh.select_all(action='SELECT')。这些都不需要,因为在您更改之前选择了整个网格。这导致选择两个立方体的网格,然后在它们两个上应用平分。这是可能的,因为 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()
于 2020-01-02T10:35:18.277 回答