These days I’m working on urban environments in Blender. Urban environments can be easily broken down into modules and series – cloning the same objects over and over to create roads, floor tilings, buildings and so forth…
Duplicating modules by hand is tedious even if you don’t care about millimeter accuracy. So I thought I’d write a little script to do simple tilings.
The script duplicates the active object several times and merges the result into a single object. The original module or ’tile’ is preserved. This script will run with Blender 2.49 and can be easily modified (for example, if you want to add padding between copies or don’t want to merge the result)
What we need to know
To retrieve the active object:
scene=Scene.GetCurrent()
active=scene.objects.active
Initially I thought about duplicating vertex data directly as I want the tiles to be part of the same object. But duplicating the object first may be safer and offers more flexibility.
We can use the following command to duplicate active objects:
Object.Duplicate() # duplicate, link mesh data
Object.Duplicate(mesh=1) # duplicate, clone mesh data
To tile clones edge to edge, we’ll need to know the extent of the object:
dimX=obj.getBoundBox()[6][0]-obj.getBoundBox()[0][0]
dimY=obj.getBoundBox()[6][1]-obj.getBoundBox()[0][1]
dimZ=obj.getBoundBox()[6][2]-obj.getBoundBox()[0][2]
Once we have duplicated and moved our objects we can merge them together using join(). This function is a member of the object class and will join the target with all objects in a given array:
arr=[]
arr.append(anObject)
obj.join(arr)
join() doesn’t delete merged objects; usually we want to delete all clones after merging. To remove an object from the scene, we can use the following command:
scene.unlink(anObj)
Reminder… to iterate in python:
for x in range(N) # e.g range 10 iterates from zero to 9
If you’re in a hurry, a modal UI provides the quick and dirty way to input data from the user:
numX = Blender.Draw.PupMenu(”X dupli%t|1|2″)
This gets the user to input either ‘1′ or ‘2′.
Complete Source Code
#!BPY
“”" Registration info for Blender menus:
Name: ‘Tile v0.0′
Blender: 249
Group: ‘Object’
Tip: ‘Tile an object along x,y,z axis and merge’
“”"
import Blender
import bpy
from Blender import *
# TILE V0.0 – A SIMPLE SCRIPT FOR TILING AND MERGING THE RESULT
# LICENSE: LGPL
def copy_and_merge(nx,ny,nz):
scene=Blender.Scene.GetCurrent()
target=scene.objects.active
dimX=target.getBoundBox()[6][0]-target.getBoundBox()[0][0]
dimY=target.getBoundBox()[6][1]-target.getBoundBox()[0][1]
dimZ=target.getBoundBox()[6][2]-target.getBoundBox()[0][2]
clones=[]
for x in range(nx):
for y in range(ny):
for z in range(nz):
Object.Duplicate(mesh=1)
clone=scene.objects.active
clone.LocX+=dimX*x
clone.LocY+=dimY*y
clone.LocZ+=dimZ*z
clones.append(clone)
clone.select(0)
target.select(1)
first=clones.pop()
first.join(clones)
for k in clones: scene.unlink(k)
# ————————————–
# Get the number of copies from the user and run the script
numX = Blender.Draw.PupMenu(“X dupli%t|1|2|3|4|5|5|6|7|8|9|10″)
numY = Blender.Draw.PupMenu(“Y dupli%t|1|2|3|4|5|5|6|7|8|9|10″)
numZ = Blender.Draw.PupMenu(“Z dupli%t|1|2|3|4|5|5|6|7|8|9|10″)
copy_and_merge(numX,numY,numZ)
# END ————————————
This is it. Modifying the script just a little can help you make staircases, fences and all kind of stuff, so I think it’s a nice introduction to how scripting can help generating scenes quickly and easily.