Python 如何使用Blender脚本删除场景中较小的多个对象?

Python 如何使用Blender脚本删除场景中较小的多个对象?,python,blender,mesh,Python,Blender,Mesh,我用的是Blender 2.8。我想将一个对象导入blender,该对象由几个未连接的部分组成。所以我想将对象拆分,只导出最大的部分 让我们假设一个物体中有三个部分,一个大的,两个小的。我能把这个物体变成三个物体,每个物体包含一个碎片。我想删除两个较小的对象,只保留最大的一个。我在想,也许可以找到三个不同物体的表面积,只保留最大的表面积,而删除所有其他的表面积?我是搅拌机的新手 bpy.ops.import_mesh.stl(filepath='path/of/file.stl') bpy.op

我用的是Blender 2.8。我想将一个对象导入blender,该对象由几个未连接的部分组成。所以我想将对象拆分,只导出最大的部分

让我们假设一个物体中有三个部分,一个大的,两个小的。我能把这个物体变成三个物体,每个物体包含一个碎片。我想删除两个较小的对象,只保留最大的一个。我在想,也许可以找到三个不同物体的表面积,只保留最大的表面积,而删除所有其他的表面积?我是搅拌机的新手

bpy.ops.import_mesh.stl(filepath='path/of/file.stl')
bpy.ops.mesh.separate(type='LOOSE')
amount_of_pieces = len(context.selected_objects)

if amount_of_pieces > 1:
    highest_surface_area = 0

    #the rest is pseudocode
    for object in scene:
        if object.area > highest_surface_area:
            highest_surface_area = object.area
        else:
            bpy.ops.object.delete()

bpy.ops.export_mesh.stl(filepath='path/of/new/file.stl')

我能够编写一个代码来处理这个问题,但是,它非常长而且混乱。如果有人能给我一些清理的建议,我将不胜感激

import bpy
import os
import bmesh


context = bpy.context

file = (r'path\to\file.stl')

bpy.ops.import_mesh.stl(filepath= file)
fileName = os.path.basename(file)[:-4].capitalize()
bpy.ops.mesh.separate(type='LOOSE')
bpy.ops.object.select_all(action='SELECT')
piece = len(context.selected_objects)
bpy.ops.object.select_all(action='DESELECT')

high = 0
if piece > 1:
    bpy.data.objects[fileName].select_set(True)
    obj = bpy.context.active_object
    bm = bmesh.new()
    bm.from_mesh(obj.data)
    area = sum(f.calc_area() for f in bm.faces)
    high = area
    bm.free()
    bpy.ops.object.select_all(action='DESELECT')

    for x in range (1, piece):
        name = fileName + '.00' + str(x)
        object = bpy.data.objects[name]
        context.view_layer.objects.active = object
        bpy.data.objects[name].select_set(True)
        obj = bpy.context.active_object
        bm = bmesh.new()
        bm.from_mesh(obj.data)
        newArea = sum(f.calc_area() for f in bm.faces)
        bm.free()
        if newArea > high:
            high = newArea
            bpy.ops.object.select_all(action='DESELECT')
        else:
            bpy.ops.object.delete()
        bpy.ops.object.select_all(action='DESELECT')

    if area != high:
        bpy.data.objects[fileName].select_set(True)
        bpy.ops.object.delete()


bpy.ops.export_mesh.stl(filepath= 'path/to/export/file.stl')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False, confirm=False)
这些步骤将是:-

  • 导入文件
  • 分成多个对象
  • 为安全起见,请获取网格对象列表
  • 列出每个对象的表面积
  • 从区域列表中获取最大值
  • 删除不是最大的对象
  • 出口量最大
  • 清理
我们不需要使用来获得表面积,法线网格数据包括

使用,我们可以将大多数步骤分别放在一行中

import bpy

# import and separate
file = (r'path/of/file.stl')
bpy.ops.import_mesh.stl(filepath= file)
bpy.ops.mesh.separate(type='LOOSE')

# list of mesh objects
mesh_objs = [o for o in bpy.context.scene.objects
                if o.type == 'MESH']

# dict with surface area of each object
obj_areas = {o:sum([f.area for f in o.data.polygons])
                for o in mesh_objs}

# which is biggest
big_obj = max(obj_areas, key=obj_areas.get)

# select and delete not biggest
[o.select_set(o is not big_obj) for o in mesh_objs]
bpy.ops.object.delete(use_global=False, confirm=False)

#export
bpy.ops.export_mesh.stl(filepath= 'path/of/new/file.stl')

# cleanup
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False, confirm=False)