0
$\begingroup$

So I have a big level I made in blender intended for a game but I need to join models so that they become one. But there are 1057 objects in the scene and for me to join all of the objects together manually would take a while, and I don't want everything to be a single object. I basically need to join the stuff so that it becomes about 200 - 250 objects without me having to manually select equal amounts of objects to do that.

The reason I say "determined by how far away they are" is because it would really help if the things I joined were within a vicinity of each other, so the things joined are logical and in chunks instead of just "all the objects that share a material" or something.

Any addon or methods will help.

$\endgroup$
1
$\begingroup$

Make a Grid of view3d region and join via Border Select

Made an operator that splits the 3d view into an i x j grid. Joins all the meshes in each grid sector using border select. Note this is a 2D approach, and assumes that looking at your level in top view and assigning a grid will suffice. If your objects are spread more randomly in all three dimensions each joined selection would look more like a column.

After running script below, find in view3d > object > Grid Join menu.

enter image description here

Did have the View All operator in the operator, but decided it may be better to let user choose view, and zoom into all objects wishes to join.

enter image description here Divide visible screen area into a grid with 16 x segments, and 9 y segments and join those selected by border select in each.

import bpy
from bpy.props import IntProperty

class SimpleOperator(bpy.types.Operator):
    """Join objects based on View3d Grid"""
    bl_idname = "view3d.grid_join"
    bl_label = "Grid Join"
    bl_options = {'REGISTER', 'UNDO'}
    x_segments = IntProperty(default=16, min=1)
    y_segments = IntProperty(default=9, min=1)
    @classmethod
    def poll(cls, context):
        scene = context.scene
        return len([o for o in scene.objects if o.type == 'MESH'])

    def execute(self, context):
        scene = context.scene
        joined_obs = []
        bpy.ops.object.select_by_type(type='MESH')
        #bpy.ops.view3d.view_all()
        region = context.region
        print(region.width, region.height)
        w = region.width / self.x_segments
        h = region.height / self.y_segments
        for i in range(self.x_segments):
            xmin, xmax  = i * w, (i + 1) * w
            for j in range(self.y_segments):                
                ymin, ymax  = j * h, (j + 1) * h
                #print(xmin, xmax, ymin, ymax)
                bpy.ops.view3d.select_border(
                       xmin=xmin, 
                       xmax=xmax,
                       ymin=ymin,
                       ymax=ymax,
                       deselect=False,
                       extend=False)
                for o in context.selected_objects:
                    o.select = o.type == 'MESH'
                if len(context.selected_objects):
                    scene.objects.active = context.selected_objects[0]
                    bpy.ops.object.join()
                    context.object.hide = True
                    joined_obs.append(context.object)

        for o in joined_obs:
            o.hide = False
        return {'FINISHED'}

def menu_draw(self, context):
    self.layout.operator("view3d.grid_join")

def register():
    bpy.utils.register_class(SimpleOperator)
    bpy.types.VIEW3D_MT_object.prepend(menu_draw)

def unregister():
    bpy.utils.unregister_class(SimpleOperator)
    bpy.types.VIEW3D_MT_object.remove(menu_draw)

if __name__ == "__main__":
    register()

    # test call
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy