Skip to main content
some comments on slight changes needed in api changes in blender 2.8
Source Link

enter image description here

A similar answer that utilizes Blender's Mathutils' Vector length property (prevents you from needing to calculate distances in all 3 axes individually):

import bpy
from random import random
from mathutils import Vector

cubeRadius    = 0.25
maxIterations = 1000 # Max iterations to prevent while loop from running forever

# min and max values for each axis for the random numbers
ranges = {
    'x' : { 'min' : -10, 'max' : 10 },
    'y' : { 'min' : -10, 'max' : 10 },
    'z' : { 'min' : -10, 'max' : 10 }
}

# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * ( ranges[axis]['max'] - ranges[axis]['min'] )

size  = 250 # Number of cubes
cubes = []  # Cube coordinates list

loopIterations = 0
while len( cubes ) < size and loopIterations < maxIterations:
    loopIterations += 1
        
    # Generate a random 3D coordinate
    loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])

    if len( cubes ) > 0:
        # Search for overlapping points (within the cube radius radius)
        overlappingPoints = [ p for p in cubes if ( p - loc ).length < cubeRadius * 2 ]

        # if any found, skip this location
        if overlappingPoints: continue
    
    # Add coordinate to cube list
    cubes.append( loc )

# Add the first cube (others will be duplicated from it)
# Note: in blender 2.8 size arg is used instead of radius
bpy.ops.mesh.primitive_cube_add( radius = cubeRadius, location = cubes[0] ) 

cube = bpy.context.scene.objects['Cube']

# Add all other cubes
for c in cubes[1:]:
    dupliCube = cube.copy()
    dupliCube.location = c
    bpy.context.scene.objects.link( dupliCube )
    # in blender 2.8 an api change requires to use the collection instead of the scene
    # bpy.context.collection.objects.link(dupliCube)

enter image description here

A similar answer that utilizes Blender's Mathutils' Vector length property (prevents you from needing to calculate distances in all 3 axes individually):

import bpy
from random import random
from mathutils import Vector

cubeRadius    = 0.25
maxIterations = 1000 # Max iterations to prevent while loop from running forever

# min and max values for each axis for the random numbers
ranges = {
    'x' : { 'min' : -10, 'max' : 10 },
    'y' : { 'min' : -10, 'max' : 10 },
    'z' : { 'min' : -10, 'max' : 10 }
}

# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * ( ranges[axis]['max'] - ranges[axis]['min'] )

size  = 250 # Number of cubes
cubes = []  # Cube coordinates list

loopIterations = 0
while len( cubes ) < size and loopIterations < maxIterations:
    loopIterations += 1
        
    # Generate a random 3D coordinate
    loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])

    if len( cubes ) > 0:
        # Search for overlapping points (within the cube radius radius)
        overlappingPoints = [ p for p in cubes if ( p - loc ).length < cubeRadius * 2 ]

        # if any found, skip this location
        if overlappingPoints: continue
    
    # Add coordinate to cube list
    cubes.append( loc )

# Add the first cube (others will be duplicated from it)
bpy.ops.mesh.primitive_cube_add( radius = cubeRadius, location = cubes[0] )
cube = bpy.context.scene.objects['Cube']

# Add all other cubes
for c in cubes[1:]:
    dupliCube = cube.copy()
    dupliCube.location = c
    bpy.context.scene.objects.link( dupliCube )

enter image description here

A similar answer that utilizes Blender's Mathutils' Vector length property (prevents you from needing to calculate distances in all 3 axes individually):

import bpy
from random import random
from mathutils import Vector

cubeRadius    = 0.25
maxIterations = 1000 # Max iterations to prevent while loop from running forever

# min and max values for each axis for the random numbers
ranges = {
    'x' : { 'min' : -10, 'max' : 10 },
    'y' : { 'min' : -10, 'max' : 10 },
    'z' : { 'min' : -10, 'max' : 10 }
}

# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * ( ranges[axis]['max'] - ranges[axis]['min'] )

size  = 250 # Number of cubes
cubes = []  # Cube coordinates list

loopIterations = 0
while len( cubes ) < size and loopIterations < maxIterations:
    loopIterations += 1
        
    # Generate a random 3D coordinate
    loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])

    if len( cubes ) > 0:
        # Search for overlapping points (within the cube radius radius)
        overlappingPoints = [ p for p in cubes if ( p - loc ).length < cubeRadius * 2 ]

        # if any found, skip this location
        if overlappingPoints: continue
    
    # Add coordinate to cube list
    cubes.append( loc )

# Add the first cube (others will be duplicated from it)
# Note: in blender 2.8 size arg is used instead of radius
bpy.ops.mesh.primitive_cube_add( radius = cubeRadius, location = cubes[0] ) 

cube = bpy.context.scene.objects['Cube']

# Add all other cubes
for c in cubes[1:]:
    dupliCube = cube.copy()
    dupliCube.location = c
    bpy.context.scene.objects.link( dupliCube )
    # in blender 2.8 an api change requires to use the collection instead of the scene
    # bpy.context.collection.objects.link(dupliCube)
Adding gif
Source Link
TLousky
  • 16.1k
  • 1
  • 42
  • 73

enter image description here

A similar answer that utilizes Blender's Mathutils' Vector length property (prevents you from needing to calculate distances in all 3 axes individually):

import bpy
from random import random
from mathutils import Vector

cubeRadius    = 0.25
maxIterations = 1000 # Max iterations to prevent while loop from running forever

# min and max values for each axis for the random numbers
ranges = {
    'x' : { 'min' : -10, 'max' : 10 },
    'y' : { 'min' : -10, 'max' : 10 },
    'z' : { 'min' : -10, 'max' : 10 }
}

# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * ( ranges[axis]['max'] - ranges[axis]['min'] )

size  = 250 # Number of cubes
cubes = []  # Cube coordinates list

loopIterations = 0
while len( cubes ) < size and loopIterations < maxIterations:
    loopIterations += 1
        
    # Generate a random 3D coordinate
    loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])

    if len( cubes ) > 0:
        # Search for overlapping points (within the cube radius radius)
        overlappingPoints = [ p for p in cubes if ( p - loc ).length < cubeRadius * 2 ]

        # if any found, skip this location
        if overlappingPoints: continue
    
    # Add coordinate to cube list
    cubes.append( loc )

# Add the first cube (others will be duplicated from it)
bpy.ops.mesh.primitive_cube_add( radius = cubeRadius, location = cubes[0] )
cube = bpy.context.scene.objects['Cube']

# Add all other cubes
for c in cubes[1:]:
    dupliCube = cube.copy()
    dupliCube.location = c
    bpy.context.scene.objects.link( dupliCube )

A similar answer that utilizes Blender's Mathutils' Vector length property (prevents you from needing to calculate distances in all 3 axes individually):

import bpy
from random import random
from mathutils import Vector

cubeRadius    = 0.25
maxIterations = 1000 # Max iterations to prevent while loop from running forever

# min and max values for each axis for the random numbers
ranges = {
    'x' : { 'min' : -10, 'max' : 10 },
    'y' : { 'min' : -10, 'max' : 10 },
    'z' : { 'min' : -10, 'max' : 10 }
}

# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * ( ranges[axis]['max'] - ranges[axis]['min'] )

size  = 250 # Number of cubes
cubes = []  # Cube coordinates list

loopIterations = 0
while len( cubes ) < size and loopIterations < maxIterations:
    loopIterations += 1
        
    # Generate a random 3D coordinate
    loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])

    if len( cubes ) > 0:
        # Search for overlapping points (within the cube radius radius)
        overlappingPoints = [ p for p in cubes if ( p - loc ).length < cubeRadius * 2 ]

        # if any found, skip this location
        if overlappingPoints: continue
    
    # Add coordinate to cube list
    cubes.append( loc )

# Add the first cube (others will be duplicated from it)
bpy.ops.mesh.primitive_cube_add( radius = cubeRadius, location = cubes[0] )
cube = bpy.context.scene.objects['Cube']

# Add all other cubes
for c in cubes[1:]:
    dupliCube = cube.copy()
    dupliCube.location = c
    bpy.context.scene.objects.link( dupliCube )

enter image description here

A similar answer that utilizes Blender's Mathutils' Vector length property (prevents you from needing to calculate distances in all 3 axes individually):

import bpy
from random import random
from mathutils import Vector

cubeRadius    = 0.25
maxIterations = 1000 # Max iterations to prevent while loop from running forever

# min and max values for each axis for the random numbers
ranges = {
    'x' : { 'min' : -10, 'max' : 10 },
    'y' : { 'min' : -10, 'max' : 10 },
    'z' : { 'min' : -10, 'max' : 10 }
}

# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * ( ranges[axis]['max'] - ranges[axis]['min'] )

size  = 250 # Number of cubes
cubes = []  # Cube coordinates list

loopIterations = 0
while len( cubes ) < size and loopIterations < maxIterations:
    loopIterations += 1
        
    # Generate a random 3D coordinate
    loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])

    if len( cubes ) > 0:
        # Search for overlapping points (within the cube radius radius)
        overlappingPoints = [ p for p in cubes if ( p - loc ).length < cubeRadius * 2 ]

        # if any found, skip this location
        if overlappingPoints: continue
    
    # Add coordinate to cube list
    cubes.append( loc )

# Add the first cube (others will be duplicated from it)
bpy.ops.mesh.primitive_cube_add( radius = cubeRadius, location = cubes[0] )
cube = bpy.context.scene.objects['Cube']

# Add all other cubes
for c in cubes[1:]:
    dupliCube = cube.copy()
    dupliCube.location = c
    bpy.context.scene.objects.link( dupliCube )
Source Link
TLousky
  • 16.1k
  • 1
  • 42
  • 73

A similar answer that utilizes Blender's Mathutils' Vector length property (prevents you from needing to calculate distances in all 3 axes individually):

import bpy
from random import random
from mathutils import Vector

cubeRadius    = 0.25
maxIterations = 1000 # Max iterations to prevent while loop from running forever

# min and max values for each axis for the random numbers
ranges = {
    'x' : { 'min' : -10, 'max' : 10 },
    'y' : { 'min' : -10, 'max' : 10 },
    'z' : { 'min' : -10, 'max' : 10 }
}

# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * ( ranges[axis]['max'] - ranges[axis]['min'] )

size  = 250 # Number of cubes
cubes = []  # Cube coordinates list

loopIterations = 0
while len( cubes ) < size and loopIterations < maxIterations:
    loopIterations += 1
        
    # Generate a random 3D coordinate
    loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])

    if len( cubes ) > 0:
        # Search for overlapping points (within the cube radius radius)
        overlappingPoints = [ p for p in cubes if ( p - loc ).length < cubeRadius * 2 ]

        # if any found, skip this location
        if overlappingPoints: continue
    
    # Add coordinate to cube list
    cubes.append( loc )

# Add the first cube (others will be duplicated from it)
bpy.ops.mesh.primitive_cube_add( radius = cubeRadius, location = cubes[0] )
cube = bpy.context.scene.objects['Cube']

# Add all other cubes
for c in cubes[1:]:
    dupliCube = cube.copy()
    dupliCube.location = c
    bpy.context.scene.objects.link( dupliCube )