Creating a script callable with a shortcut + quick boolean merging and removing

I’m new to Python (and Python) and I needed a way to quickly join objects. The existing join gives a lot of problems with manifold to my knowledge leaving only the boolean union. But using it is such a pain in the ass as I have to click a million time to achieve something utterly basic. So I created a script that gives the following shortcuts:

  • shift+plus: join 2 or more objects (boolean UNION way) and keep the non active ones leaving both the merged and non-active ones
  • ctrl+plus: join 2 or more objects (boolean UNION way) and remove the non active ones leaving only the active one
  • shift+minus: remove non-active from active object (boolean DIFFERENCE way) and keep the non-active one leaving both the active one that has the intersecting piece chopped off and the non-active one
  • ctrl+minus: remove non-active from active object (boolean DIFFERENCE way) and remove the non-active one leaving only the active one that has the intersecting piece chopped off

The code is in Python which compared to Java notation is quite a hassle especially the tabs :frowning: Code is partially Dutch so feel free to change it. The script will override the existing numpad + (plus) and numpad - (minus) shortcuts. Feel to change that as well.

To install, it should be sufficient to save the content in a file for example worb.py and then go to File > User preferences > Install from file > {select your file} > {if it worked go to Category Object with Supported level “Community” active} > {activate checkbox for the line “Object: WORB”}

Hope this post is any way useful.

bl_info = {
    "name": "WORB",
    "category": "Object",
}

import bpy
print("-- SCRIPT WORB --")

class BijvoegenResidu(bpy.types.Operator):
    """BijvoegenResidu"""
    bl_idname = "object.bijvoegen_residu"
    bl_label = "Bijvoegen Residu"
    bl_options = {'REGISTER', 'UNDO'}


    def execute(self, context):

        actiefObject = bpy.context.scene.objects.active
        geselecteerdeObjecten = bpy.context.selected_objects 
        for object in geselecteerdeObjecten:
            if actiefObject.name != object.name:
                print("ander geselecteerd:",object.name)
                bpy.ops.object.modifier_add(type='BOOLEAN')
                bpy.context.object.modifiers["Boolean"].operation = 'UNION'
                bpy.context.object.modifiers["Boolean"].object = object
                bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")

        return {'FINISHED'}

class BijvoegenOpkuis(bpy.types.Operator):
    """BijvoegenOpkuis"""
    bl_idname = "object.bijvoegen_opkuis"
    bl_label = "Bijvoegen Opkuis"
    bl_options = {'REGISTER', 'UNDO'}


    def execute(self, context):

        actiefObject = bpy.context.scene.objects.active
        geselecteerdeObjecten = bpy.context.selected_objects 
        for object in geselecteerdeObjecten:
            if actiefObject.name != object.name:
                print("ander geselecteerd:",object.name)
                bpy.ops.object.modifier_add(type='BOOLEAN')
                bpy.context.object.modifiers["Boolean"].operation = 'UNION'
                bpy.context.object.modifiers["Boolean"].object = object
                bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")

        actiefObject = bpy.context.scene.objects.active
        actiefObject.select = False
        bpy.ops.object.delete()
        actiefObject.select = True

        return {'FINISHED'}

class WeghalenResidu(bpy.types.Operator):
    """WeghalenResidu"""
    bl_idname = "object.weghalen_residu"
    bl_label = "Weghalen Residu"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):

        actiefObject = bpy.context.scene.objects.active
        geselecteerdeObjecten = bpy.context.selected_objects 
        for object in geselecteerdeObjecten:
            if actiefObject.name != object.name:
                print("ander geselecteerd:",object.name)
                bpy.ops.object.modifier_add(type='BOOLEAN')
                bpy.context.object.modifiers["Boolean"].operation = 'DIFFERENCE'
                bpy.context.object.modifiers["Boolean"].object = object
                bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")

        return {'FINISHED'}

class WeghalenOpkuis(bpy.types.Operator):
    """WeghalenOpkuis"""
    bl_idname = "object.weghalen_opkuis"
    bl_label = "Weghalen Opkuis"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):

        actiefObject = bpy.context.scene.objects.active
        geselecteerdeObjecten = bpy.context.selected_objects 
        for object in geselecteerdeObjecten:
            if actiefObject.name != object.name:
                print("ander geselecteerd:",object.name)
                bpy.ops.object.modifier_add(type='BOOLEAN')
                bpy.context.object.modifiers["Boolean"].operation = 'DIFFERENCE'
                bpy.context.object.modifiers["Boolean"].object = object
                bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Boolean")

        actiefObject = bpy.context.scene.objects.active
        actiefObject.select = False
        bpy.ops.object.delete()
        actiefObject.select = True

        return {'FINISHED'}

# store keymaps here to access after registration
addon_keymaps = []


def register():
    bpy.utils.register_class(BijvoegenResidu)

    # handle the keymap
    wm = bpy.context.window_manager
    km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
    kmi = km.keymap_items.new(BijvoegenResidu.bl_idname, 'NUMPAD_PLUS', 'PRESS', ctrl=False, shift=True)
    addon_keymaps.append(km)

    bpy.utils.register_class(BijvoegenOpkuis)

    # handle the keymap
    wm = bpy.context.window_manager
    km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
    kmi = km.keymap_items.new(BijvoegenOpkuis.bl_idname, 'NUMPAD_PLUS', 'PRESS', ctrl=True, shift=False)
    addon_keymaps.append(km)

    bpy.utils.register_class(WeghalenResidu)

    # handle the keymap
    wm = bpy.context.window_manager
    km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
    kmi = km.keymap_items.new(WeghalenResidu.bl_idname, 'NUMPAD_MINUS', 'PRESS', ctrl=False, shift=True)
    addon_keymaps.append(km)

    bpy.utils.register_class(WeghalenOpkuis)

    # handle the keymap
    wm = bpy.context.window_manager
    km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
    kmi = km.keymap_items.new(WeghalenOpkuis.bl_idname, 'NUMPAD_MINUS', 'PRESS', ctrl=True, shift=False)
    addon_keymaps.append(km)

def unregister():
    bpy.utils.unregister_class(BijvoegenResidu)
    bpy.utils.unregister_class(BijvoegenOpkuis)
    bpy.utils.unregister_class(WeghalenResidu)
    bpy.utils.unregister_class(WeghalenOpkuis)

    # handle the keymap
    wm = bpy.context.window_manager
    for km in addon_keymaps:
        wm.keyconfigs.addon.keymaps.remove(km)
    # clear the list
    del addon_keymaps[:]


if __name__ == "__main__":
    register()