Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Blender addon to distribute objects along an axis
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
############################################################################
# Installation info
#
# Download file somewhere to your computer.
# In Blender go to edit > preferences > addons
# Click install and select the file.
# This copies the file to Blender so you may delete the original
bl_info = {
"name": "Distribute Objects",
"description": "Distribute objects along an axis",
"author": "Jake Coxon",
"version": (0, 1, 0, 20201224),
"blender": (2, 91, 0),
"category": "UI"
}
import bpy
import mathutils
import math
from functools import partial
from bpy.props import *
from mathutils import Vector, Matrix
class DistributeObjectsOperator(bpy.types.Operator):
bl_idname = "distribute.distributeobjects"
bl_label = "Distribute Objects"
bl_options = {'REGISTER', 'UNDO'}
axis: EnumProperty(
name="Axis",
description="Axis selection",
items= [('x', "X", ""),('y', "Y", ""),('z', "Z","")],
default='x'
)
margin: bpy.props.FloatProperty(name="Margin")
def execute(self, contecxt):
objs = bpy.context.selected_objects
MD = 0
if len(objs) <= 1:
return {'CANCELLED'}
first = objs[0]
gap = abs(self.margin)
direction = Vector((0, 0, 0))
setattr(direction, self.axis, 1)
if self.margin < 0:
direction *= -1
def axis(vec):
return getattr(vec, self.axis)
def point_to_world_coords(obj, t):
return obj.matrix_world @ Vector((*t, 0))
def world_bounds(obj):
return [axis(point_to_world_coords(obj, q)) for q in obj.bound_box]
new_position = first.location + direction * min(world_bounds(first))
for obj in objs:
new_position -= direction * min(world_bounds(obj))
obj.location = new_position
new_position += direction * (max(world_bounds(obj)) + gap)
return {'FINISHED'}
def invoke(self, context, event):
if len(context.selected_objects) <= 1:
self.report({'WARNING'}, "Not enough objects selected")
return {'CANCELLED'}
self.execute(context)
return context.window_manager.invoke_props_popup(self, event)
def menu_func(self, context):
self.layout.operator(DistributeObjectsOperator.bl_idname)
def register():
bpy.types.VIEW3D_MT_object.append(menu_func)
bpy.utils.register_class(DistributeObjectsOperator)
def unregister():
bpy.types.VIEW3D_MT_object.remove(menu_func)
bpy.utils.unregister_class(DistributeObjectsOperator)
if __name__ == "__main__":
register()
@JakeCoxon
Copy link
Author

JakeCoxon commented Dec 24, 2020

Screenshot 2020-12-24 213427

@amaliac627
Copy link

amaliac627 commented Jan 20, 2021

This is a great solution, though I'm having serious issues adding the add on to blender...help! I'm on a mac if that matters. I tried googling and no luck

@JakeCoxon
Copy link
Author

JakeCoxon commented Jan 20, 2021

Hi @amaliac627 what are the issues? Did you try the installation instructions at the top of the file? What version of Blender are you using? To download the file right click the Raw button at the top and choose "Save link as" or equivalent.

@amaliac627
Copy link

amaliac627 commented Jan 20, 2021

@amaliac627
Copy link

amaliac627 commented Jan 20, 2021

@JakeCoxon
Copy link
Author

JakeCoxon commented Jan 21, 2021

@amaliac627 TextEdit is for saving rich text documents not code so the file format that it uses contains extra data, regardless of the file extension you use. You should right click the above Raw button and choose "Save link as" to save it to your computer, this will make sure you are saving the plain text file exactly as it should be

@amaliac627
Copy link

amaliac627 commented Jan 21, 2021

@JakeCoxon
Copy link
Author

JakeCoxon commented Jan 21, 2021

The above error is because you saved it using TextEdit

@amaliac627
Copy link

amaliac627 commented Jan 21, 2021

I just saved that file raw from here and saved it and I got the same error.

@amaliac627
Copy link

amaliac627 commented Jan 21, 2021

Screen Shot 2021-01-21 at 4 01 10 PM

@JakeCoxon
Copy link
Author

JakeCoxon commented Jan 21, 2021

@amaliac627 The error indicates that the file is still rich text format, make sure to replace that file with the raw file you downloaded

@hankdendrijver
Copy link

hankdendrijver commented Jan 29, 2021

Aren't we forgetting something, miss Amaliac627?
A "thank you" perhaps?
Sigh. Privileged millennial.

Wonderful code btw, Jake. Thanks.

@amaliac627
Copy link

amaliac627 commented Jan 29, 2021

I was getting that error when I downloaded the file straight from here...but I troubleshooted myself and got it to work...but thank you! I got it to work and have been using the add-on often.

@JakeCoxon
Copy link
Author

JakeCoxon commented Jan 29, 2021

@amaliac627 I'm glad you got it to work!

@flipityflop
Copy link

flipityflop commented Feb 25, 2021

Hey, thanks for the code pretty awesome.
First, for anyone struggling you gotta unzip the file and install the .py, which is what I couldnt figure out, some add-ons I've installed in the past don't require you to do that, also you don't get an error message from Blender if you install the .zip file, and then you just waste time trying to find the add-on.
Second, from what I can tell from testing, it distributes from the 3d cursor, so if you select the first object, then hit Objects>Snap>Cursor to Selected, than it wont move all your objects and redistribute if you still have the 3d cursor at the default center, I think? Not sure, its weird, but it definitely does some jumpy stuff

@iandol
Copy link

iandol commented Mar 3, 2021

@JakeCoxon -- super big thank you for sharing this, works well in Blender 2.91.2 under Linux.

@Iglum
Copy link

Iglum commented Mar 21, 2021

This is super! Thank you for this little script. Gonna fit right into my Quick favorites menu

@gitsamhub
Copy link

gitsamhub commented Jun 17, 2021

@JakeCoxon
thank you very much for such a simple but important utility.
I am surprised and frustrated to see that Blender doesn't have distribute objects function built in.

@arminhupka
Copy link

arminhupka commented Sep 8, 2021

I tried to use this with v2.93 but distribution settings are not displayed. Any tips?

@Kurt-gbg
Copy link

Kurt-gbg commented Sep 21, 2021

I have it working in 2.93.3. For what I do it is really useful. Thank you !!!

@Subjoys
Copy link

Subjoys commented Oct 27, 2021

Hey @JakeCoxon, I feel very silly asking this, but how do you actually pull up the UI to use the tool..... Download went smoothly but actually accessing the tool is proving to be difficult

@RealmsGames-Admin
Copy link

RealmsGames-Admin commented Nov 12, 2021

I tried to use this with v2.93 but distribution settings are not displayed. Any tips?

Had the same issue in 2.93. Seems to bring up the menu if you activate the add-on by Edit > Menu Search > DIstribute Objects

Thanks to the creator for sharing such a great addon!

PS Enabling a second layer of distribution with say N Objects per axis would be amazing! Eg 10 Objects in X Axis at 5m apart, with additional rows in Y Axis at 10m apart.

@SaschaLiebmann
Copy link

SaschaLiebmann commented Mar 31, 2022

Thanks it works like a charm and i use it quite frequently!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment