import bpy

from mathutils import Vector, Matrix
from math import pi

def slice_object(object, punch, use_ops_method=False):
    if object.type != 'MESH': return
    print('slicing', object.name, 'with',punch.name)
    if object == punch:
        print(object.name, punch.name)
        return
    if object.data.users > 1:
        print(object.name, ' data already has users, skipping slice')
        return
    object.modifiers.new('cut', type = 'BOOLEAN')
    object.modifiers['cut'].operation = 'DIFFERENCE'
    object.modifiers['cut'].object = punch
    if use_ops_method:
        bpy.context.view_layer.objects.active = object
        bpy.ops.object.modifier_apply(apply_as='DATA', modifier='cut')
        return
    # Save old mesh    
    old_mesh = object.data

    #new_mesh = object.to_mesh(scene=bpy.context.scene, apply_modifiers=True, settings='PREVIEW')
    new_mesh = object.to_mesh()
    

    
    print('sliced number of vertices: ', len(new_mesh.vertices))
    object.data = new_mesh

    # Cleanup
    print('cleaning up')
    object.modifiers.clear()
    bpy.data.meshes.remove(old_mesh)
    
    #name = 'sliced_'+object.name
    #object.name = name
    
    
def cube_slicer(location=(0,0,0)):    
    bpy.ops.mesh.primitive_cube_add(location=location)
    punch = bpy.context.view_layer.objects.active
    punch.name = 'slicer'
    #Shift up and move to obj
    #punch.scale = Vector((5,1,1))
    # Scale doesn't work properly. Scale by hand:
    mat = Matrix([[5,0,0],[0,1,0],[0,0,1]])
    for v in punch.data.vertices:
        v.co = mat @ v.co 
    print('punch.name = ', punch.name)
    return punch
    
def slice_all():
    i = 1
    punch = cube_slicer(location=(0,0, 1))
    imax = len(bpy.data.objects)
    olist = [o for o in bpy.data.objects]
    #myo = bpy.context.scene.objects.active 
    #olist = [o for o in bpy.data.objects]
    #olist = [myo]
    for o in olist:
        if o == punch: continue
        print(o.name, i, '/', imax)
        slice_object(o, punch)
        i = i + 1    
    bpy.context.scene.objects.active = punch
    bpy.ops.object.delete()
    
if __name__=='__main__':
    slice_all()

#    i = 1
 #   object = bpy.context.scene.objects.active
#    punch= plane_slicer(location=(0,0,0))
    #slice(o, plane)
   # object.modifiers.new('Boolean', type = 'BOOLEAN')
#    print('2')
  #  object.modifiers["Boolean"].object = punch
#    print('3')
 #   object.modifiers["Boolean"].operation = 'DIFFERENCE'
#    print('4')
    
#    bpy.context.scene.objects.active = object
 #   bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")
    #new_mesh = object.to_mesh(scene=bpy.context.scene, apply_modifiers=True, settings='PREVIEW')
    #new_mesh.name = 'sliced_'+new_mesh.name
    #object.data = new_mesh
    #print('5')
    
    
    
    #imax = len(bpy.data.objects)
    
    #slice_object_with(o, plane)
    

    #for o in bpy.data.objects:
    #    if o == plane: continue
    #    print(o.name, i, '/', imax)
    #    slice_object_with(o, plane)
    #    i = i + 1
        
    #bpy.context.scene.objects.active = plane
    #bpy.ops.object.delete()