I've recently just had the same problem, the trick for me was to use bmesh.ops.triangle_fill
Collect the edges after bpy.ops.mesh.bisect
and use them as the edges=
in bmesh.ops.triangle_fill
EDIT
Added code for this to your code.
Also, you should learn to work in the bmesh ops as often as you can, it's much faster and more flexible, although more dificult to learn it has many benefits
EDIT 2
The following code is your full script with the added clean up using mesh.ops.remove_doubles
(being that the imported file scale is SO huge, you may need to increase the dist=0.5
value) and face filling using bmesh.ops.triangle_fill
import bpy
import csv
import bmesh
from mathutils import Vector
def triangulate_object(obj):
me = obj.data
# Get a BMesh representation
bm = bmesh.new()
bm.from_mesh(me)
bmesh.ops.triangulate(bm, faces=bm.faces[:])
# V2.79 : bmesh.ops.triangulate(bm, faces=bm.faces[:], quad_method=0, ngon_method=0)
# Finish up, write the bmesh back to the mesh
bm.to_mesh(me)
bm.free()
### Function to do cutouts
def SubtractObjects(name_a, name_b, new_one_name):
# Create a boolean modifier named 'my_bool_mod' for the cube.
mod_bool = name_a.modifiers.new('my_bool_mod', 'BOOLEAN')
# Set the mode of the modifier to DIFFERENCE.
mod_bool.operation = 'DIFFERENCE' #'DIFFERENCE'
# Set the object to be used by the modifier.
mod_bool.object = name_b
bpy.context.view_layer.objects.active = name_a
# Apply the modifier.
res = bpy.ops.object.modifier_apply(modifier = 'my_bool_mod')
#name_b.select_set(True) # 2.8+
#bpy.ops.object.delete()
name_a.name = new_one_name
return res
###Make cutout object
def MakeCutoutObject(objname):
bpy.ops.mesh.primitive_cube_add(size=20.0, calc_uvs=True, enter_editmode=False, align='WORLD', location=(+10.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), scale=(1.0, 1.0, 1.0))
obj = bpy.context.active_object
obj.name = objname
return obj
#print("Scale change in blender")
#oldscale = bpy.context.scene.unit_settings.scale_length
#bpy.context.scene.unit_settings.scale_length = 100
print("Starting import")
prior_objects = [object.name for object in bpy.context.scene.objects]
prior_objects_master = [object.name for object in bpy.context.scene.objects if not object.parent]
#import objects
bpy.ops.import_scene.gltf(filepath='0_L3MO_converted.gltf')
new_current_objects_master = [object.name for object in bpy.context.scene.objects if not object.parent]
new_objects_master = set(new_current_objects_master)-set(prior_objects_master)
new_current_objects = [object.name for object in bpy.context.scene.objects]
new_objects = set(new_current_objects)-set(prior_objects)
##set scale
#print("change scale back to normal")
#bpy.context.scene.unit_settings.scale_length = oldscale
#setState0()
bpy.ops.object.select_all(action='DESELECT')
Objcounter = 0
for ob in new_objects:
Objcounter+=1
obj = bpy.data.objects[ob]
if obj.type == 'EMPTY':
print("At "+str(Objcounter)+"/"+str(len(new_objects))+" Object is empty, skipping")
if obj.type != 'EMPTY':
bpy.context.view_layer.objects.active = None
bpy.ops.object.select_all(action='DESELECT')
print("At "+str(Objcounter)+"/"+str(len(new_objects))+" Now bisecting: "+ob)
#from help
#bpy.ops.mesh.bisect(plane_co=(0.0, 0.0, 0.0), plane_no=(0.0, 0.0, 0.0), use_fill=False, clear_inner=False, clear_outer=False, threshold=0.0001, xstart=0, xend=0, ystart=0, yend=0, flip=False, cursor=5)
bpy.context.view_layer.objects.active = obj
bpy.data.objects[obj.name].select_set(True)
# bpy.ops.mesh.remove_doubles(threshold=0.5, use_unselected=True, use_sharp_edge_from_normals=False)
bpy.ops.object.editmode_toggle()
### NEW CODE START ###
# crerate new bmesh object
bm_bisect = bmesh.from_edit_mesh(obj.data)
bmesh.ops.remove_doubles(bm_bisect, verts=bm_bisect.verts, dist=0.5)
# Concatenate the mesh's vertices, edges and faces into a single list
geom_0 = list(bm_bisect.verts) + list(bm_bisect.edges) + list(bm_bisect.faces)
# Bisect the mesh
ret = bmesh.ops.bisect_plane(bm_bisect, geom=geom_0, dist=0.1, plane_co=(0.0, 0.0, 0.0), plane_no=(1.0, 0.0, 0.0), use_snap_center=False, clear_inner=False, clear_outer=True)
# Retrieve only the edges from the returned geometry
edge_list = [edges for edges in ret["geom_cut"] if isinstance(edges, bmesh.types.BMEdge)]
del ret
# fill the faces
bmesh.ops.triangle_fill(bm_bisect, edges=edge_list)
# update the original objects mesh data
bmesh.update_edit_mesh(obj.data)
# remove the bmesh object
bm_bisect.free()
### NEW CODE END ###
bpy.ops.object.editmode_toggle()
#close faces
#triangulate_object(obj)
#rename master
for ob in new_objects_master:
print("Now dealing with object: "+ob)
obj = bpy.data.objects[ob]
obj.name = "0_L3MO"
##remove cutout afterwards
#bpy.ops.object.select_all(action='DESELECT')
#cutout.select_set(True) # 2.8+
#bpy.ops.object.delete()
print("Will now save import")
bpy.ops.wm.save_mainfile()
This has the added benefit of leaving any internal edges (holes) in the cut plane unfilled