#!BPY # """ # Name: 'Auto Tile' # Blender: 244 # Group: 'Object' # Tooltip: 'creates tiled clones' # """ __author__ = 'Paul Spooner, aka "Dudecon" or "Ziggy"' __version__ = '0.3 2007/09/22' __url__ = ["Author's site, http://www.peripheralarbor.com"] __email__ = ["Author's personal e-mail, dudecon:hotmail*com"] __bpydoc__ = """\ This script creates tiled spaces with clone copies of the selected object. """ # Version History: # V 0.1 2007/9/18 First release # V 0.2 2007/9/20 Added the boundary filling option # V 0.3 2007/9/22 Added lattice deform and a short description to presets from Blender import * from Blender.Mathutils import Vector import math from math import fmod, floor PI = math.pi #GLOBAL MENU VARIABLES scn = Scene.GetCurrent() ob = scn.objects.active xnum = Draw.Create(8) # number of columns ynum = Draw.Create(8) # number of rows xsize = Draw.Create(1.0) # spacing between columns ysize = Draw.Create(1.0) # spacing between rows xrot = Draw.Create(0) yrot = Draw.Create(0) xmir = Draw.Create(0) xrim = Draw.Create(0) ymir = Draw.Create(0) yrim = Draw.Create(0) xrot2 = Draw.Create(0) yrot2 = Draw.Create(0) xmir2 = Draw.Create(0) xrim2 = Draw.Create(0) ymir2 = Draw.Create(0) yrim2 = Draw.Create(0) dub = Draw.Create(0) mir = Draw.Create(0) exrot = Draw.Create(0) el = Draw.Create(3) Presets = Draw.Create(1) PresetText = "Presets%t|Square 1 (basic square and triangle tile)|Square 2 (x mirrored rows)|Square 3 (x mirrored rows and columns)|Square 4 (x mirrored columns)|Square 5 (rotated pairs)|Square 6 (rotated quads)|Square 7 (mirrored pairs)|Square 8 (mirrored quads, ie seamless)|Square 9 (offset mirrored quads)|Square 10 (mirrored rotated quads)|Square 11 (sets of eight, rotated and mirrored)|%l|Hexagonal|Triangular 1 (sets of three)|Triangular 2 (mirrored sets)|Triangular 3 (mirrored sets, offset)|Triangular 4 (mirrored sets of 12)" boundname = Draw.Create("") addlattice = Draw.Create(0) bounds = None Go = 0 #Quick Documentation: #set 'number' below to set many times to tile #at the end of the script call one of the functions (1 thru 17) and it will #make clone copies of the selected object at the origin #if you are using the "TileExample.blend" file, for best results: #select Cube for patterns 1 to 11 #select Cube.001 for pattern 12 #select Cylinder for patterns 13-16 #select Cylinder.001 for pattern 17 def squarepattern(xnum,ynum,xsize,ysize,xrot = 0, yrot = 0, xmir = 0, xrim = 0, ymir = 0, yrim = 0, xrot2 = 0, yrot2 = 0, xmir2 = 0, xrim2 = 0, ymir2 = 0, yrim2 = 0, dub = 0,xstart = 0, ystart = 0): global Go, bounds for x in range(xstart,xnum): for y in range(ystart,ynum): if bounds: for face in bounds.faces: if Geometry.PointInTriangle2D(Vector([x*xsize,y*ysize,0]), Vector(face.verts[0].co), Vector(face.verts[2].co), Vector(face.verts[1].co)) or Geometry.PointInTriangle2D(Vector([x*xsize,y*ysize,0]), Vector(face.verts[0].co), Vector(face.verts[1].co), Vector(face.verts[2].co)): Go = 1 break elif len(face.verts) == 4 and (Geometry.PointInTriangle2D(Vector([x*xsize,y*ysize,0]), Vector(face.verts[0].co), Vector(face.verts[2].co), Vector(face.verts[3].co)) or Geometry.PointInTriangle2D(Vector([x*xsize,y*ysize,0]), Mathutils.Vector(face.verts[0].co), Vector(face.verts[3].co), Vector(face.verts[2].co))): Go = 1 break else: Go = 1 if not Go: continue newob = scn.objects.new(ob.data, ob.name) newob.loc = [x*xsize,y*ysize,0] if fmod(x,2): newob.RotZ += xrot*PI/2 if xmir: newob.SizeX = -1*newob.SizeX if xrim: newob.SizeY = -1*newob.SizeY if fmod(x/2,2): newob.RotZ += xrot2*PI/2 if xmir2: newob.SizeX = -1*newob.SizeX if xrim2: newob.SizeY = -1*newob.SizeY if fmod(y,2): newob.RotZ += -yrot*PI/2 if ymir: newob.SizeY = -1*newob.SizeY if yrim: newob.SizeX = -1*newob.SizeX if fmod(y/2,2): newob.RotZ += -yrot2*PI/2 if ymir2: newob.SizeY = -1*newob.SizeY if yrim2: newob.SizeX = -1*newob.SizeX if (fmod(y,2) and fmod(x,2)): newob.RotZ += xrot*yrot*PI if (fmod(y/2,2) and fmod(x/2,2)): newob.RotZ += xrot2*yrot2*PI if dub: newob.RotZ += -newob.SizeX*PI/2 newob.SizeX = -1*newob.SizeX Go = 0 def hexpattern(xnum,ynum,xsize,ysize,mir=0,exrot=0,el=2,dub=0,xstart = 0, ystart = 0): global Go, bounds for x in range(xstart,xnum): for y in range(ystart,ynum): if x: loc = [xsize*x*3/2.0,ysize*(y*2-fmod(x,2)*(x/abs(x)))*math.sqrt(3)/2.0,0] else: loc = [0,ysize*(y*2-fmod(x,2))*math.sqrt(3)/2.0,0] if bounds: for face in bounds.faces: if Geometry.PointInTriangle2D(Vector(loc), Vector(face.verts[0].co), Vector(face.verts[2].co), Vector(face.verts[1].co)) or Geometry.PointInTriangle2D(Vector(loc), Vector(face.verts[0].co), Vector(face.verts[1].co), Vector(face.verts[2].co)): Go = 1 break elif len(face.verts) == 4 and (Geometry.PointInTriangle2D(Vector(loc), Vector(face.verts[0].co), Vector(face.verts[2].co), Vector(face.verts[3].co)) or Geometry.PointInTriangle2D(Vector(loc), Mathutils.Vector(face.verts[0].co), Vector(face.verts[3].co), Vector(face.verts[2].co))): Go = 1 break else: Go = 1 if not Go: continue if el==0: newob = scn.objects.new(ob.data, ob.name) newob.loc = loc newob.RotZ += exrot*PI/6.0 if fmod(x,2): newob.RotZ += PI Go = 0 continue for i in range(6): if el==1 and fmod(i,2): continue newob = scn.objects.new(ob.data, ob.name) newob.loc = loc newob.RotZ = PI*(i/3.)-exrot*PI/6.0 if dub: newob.SizeX = -1 if mir and fmod(i,2): newob.SizeX = -1*newob.SizeX Go = 0 def main(type=0): global scn, ob, corners, bounds scn = Scene.GetCurrent() ob = scn.objects.active if ob == None: return try: bob = Object.Get(boundname.val) except: bob = None if bob and bob.type == 'Mesh': bounds = bob.getData(mesh=True) elif bob and bob.type == 'Curve' and bob.data.isCyclic(): bounds = Mesh.New() bounds.getFromObject(bob.name) if bob: oldloc, bob.loc = bob.loc, [0.,0.,0.] oldrot, bob.rot = [bob.RotX, bob.RotY, bob.RotZ], [0.,0.,0.] oldsize, bob.size = bob.size, [1.,1.,1.] scn.objects.active = bob Window.RedrawAll() corners = [bob.boundingBox[0][0]/xsize.val,bob.boundingBox[0][1]/ysize.val , bob.boundingBox[7][0]/xsize.val, bob.boundingBox[7][1]/ysize.val] if type == 1: corners = [corners[0]*2/3,corners[1]/math.sqrt(3),corners[2]*2/3,corners[3]/math.sqrt(3)] else: corners = [0,0,xnum.val-1,ynum.val-1] scn.objects.selected = [] if type == 0: squarepattern(int(corners[2])+1,int(corners[3])+1,xsize.val,ysize.val,xrot.val, yrot.val, xmir.val, xrim.val, ymir.val, yrim.val, xrot2.val, yrot2.val, xmir2.val, xrim2.val, ymir2.val, yrim2.val,0,int(corners[0]),int(corners[1])) if dub.val: squarepattern(int(corners[2])+1,int(corners[3])+1,xsize.val,ysize.val,xrot.val, yrot.val, xmir.val, xrim.val, ymir.val, yrim.val, xrot2.val, yrot2.val, xmir2.val, xrim2.val, ymir2.val, yrim2.val, dub.val,int(corners[0]),int(corners[1])) elif type == 1: hexpattern(int(corners[2])+1,int(corners[3])+1,xsize.val,ysize.val,mir.val,exrot.val,el.val-1,0,int(corners[0]),int(corners[1])) if dub.val: hexpattern(int(corners[2])+1,int(corners[3])+1,xsize.val,ysize.val,mir.val,exrot.val,el.val-1,dub.val,int(corners[0]),int(corners[1])) if addlattice.val: latdata = Lattice.New() #latdata.setPartitions(2,2,2) latob = scn.objects.new(latdata) latob.size = [(corners[2]-corners[0])*xsize.val,(corners[3]-corners[1])*ysize.val,1] for ob in scn.objects.selected: if ob == latob: continue mod= ob.modifiers.append(Modifier.Type.LATTICE) mod[Modifier.Settings.OBJECT] = latob ob.makeDisplayList() if bob: bob.makeParent(scn.objects.selected) bob.loc, bob.rot, bob.size = oldloc, oldrot, oldsize scn.objects.active = ob elif addlattice.val: latob.loc = [(xnum.val-1)*xsize.val/2., (ynum.val-1)*ysize.val/2.,0] Window.RedrawAll() def buttonreset(): xrot.val = 0 yrot.val = 0 xmir.val = 0 xrim.val = 0 ymir.val = 0 yrim.val = 0 xrot2.val = 0 yrot2.val = 0 xmir2.val = 0 xrim2.val = 0 ymir2.val = 0 yrim2.val = 0 dub.val = 0 mir.val = 0 exrot.val = 0 el.val = 3 def draw(): global sqr, hex, exit, Presets, PresetText, boundname, addlattice global xnum, ynum, xsize, ysize, xrot, yrot, xmir, xrim, ymir, yrim global xrot2, yrot2, xmir2, xrim2, ymir2, yrim2, dub, mir, exrot, el Draw.Label("Duplicate and Tile",10,390,300,30) boundname = Draw.String("Boundary Object: ", 23, 10, 350,300,30,boundname.val,50,"This mesh or closed curve will be filled in its local x-y plane, overrides 'NumX' and 'NumY'") xnum = Draw.Number("Num X",4,10, 320, 80, 30,xnum.val,1,500,"Number of columns") ynum = Draw.Number("Num Y",5,90, 320, 80, 30,ynum.val,1,500,"Number of rows") xsize = Draw.Number("Dim X",6,170, 320, 80, 30,xsize.val,0.0,50.0,"Spacing of columns (times 2*sqrt(3) for hex)") ysize = Draw.Number("Dim Y",7,250, 320, 80, 30,ysize.val,0.0,50.0,"Spacing of rows (times 2 for hex)") Presets = Draw.Menu(PresetText,1,10,280,300,30,Presets.val,"Some nice tiling settings") sqr = Draw.PushButton("Square pattern", 2,10,240,200,30,"Makes a square pattern with the active object") Draw.Label("Every column/row",10,220,200,20) Draw.Label("On X",10,200,40,20) xmir = Draw.Toggle("MirX",8,50,200,30,20,xmir.val,"Mirror on the X axis as X increases") xrim = Draw.Toggle("MirY",9,80,200,30,20,xrim.val,"Mirror on the Y axis as X increases") xrot = Draw.Number("Rot",10,110,200,80,20,xrot.val,0,2,"How much to rotate each time X increases") Draw.Label("On Y",10,180,40,20) yrim = Draw.Toggle("MirX",11,50,180,30,20,yrim.val,"Mirror on the X axis as Y increases") ymir = Draw.Toggle("MirY",12,80,180,30,20,ymir.val,"Mirror on the Y axis as Y increases") yrot = Draw.Number("Rot",13,110,180,80,20,yrot.val,0,2,"How much to rotate each time Y increases") Draw.Label("Every two columns/rows",10,160,200,20) Draw.Label("On X",10,140,40,20) xmir2 = Draw.Toggle("MirX",14,50,140,30,20,xmir2.val,"Mirror on the X axis as X increases by two") xrim2 = Draw.Toggle("MirY",15,80,140,30,20,xrim2.val,"Mirror on the Y axis as X increases by two") xrot2 = Draw.Number("Rot",16,110,140,80,20,xrot2.val,-1,2,"How much to rotate each time X increases by two") Draw.Label("On Y",10,120,40,20) yrim2 = Draw.Toggle("MirX",17,50,120,30,20,yrim2.val,"Mirror on the X axis as Y increases by two") ymir2 = Draw.Toggle("MirY",18,80,120,30,20,ymir2.val,"Mirror on the Y axis as Y increases by two") yrot2 = Draw.Number("Rot",19,110,120,80,20,yrot2.val,-1,2,"How much to rotate each time Y increases by two") hex = Draw.PushButton("Hexagonal/triangular pattern", 3,10,70,200,30,"Makes a hexagonal pattern with the active object") mir = Draw.Toggle("Mir",20,10,40,40,20,mir.val,"Mirror every other element") exrot = Draw.Toggle("ExRot",21,60,40,40,20,exrot.val,"Adds an extra 30deg rotation to every element") el = Draw.Menu("Number Of Elements%t|One|Three|Six",22,100,40,100,20,el.val,"Chose how many elements per hexagon") Draw.Label("Misc Settings", 220,255,100,20) dub = Draw.Toggle("Double Elements",4,220,215,100,20,dub.val,"Enables mirrored and rotated copies at all locations, use with care") addlattice = Draw.Toggle("Lattice Deform", 24, 220, 235, 100, 20, addlattice.val, "creates a lattice and deforms all of the new objects with it") exit = Draw.PushButton("Exit", 0,150,10,100,20,"exits the script") def event(evt,val): if (evt==Draw.ESCKEY and not val): Draw.Exit() def bevent(evt): if evt == 0: Draw.Exit() if evt == 1: if Presets.val == 0: Return elif Presets.val == 1: buttonreset() elif Presets.val == 2: buttonreset() yrim.val=1 elif Presets.val == 3: buttonreset() yrim.val=1 xmir.val=1 elif Presets.val == 4: buttonreset() xmir.val=1 elif Presets.val == 5: buttonreset() xrot.val=2 yrim.val=1 elif Presets.val == 6: buttonreset() yrot.val=1 xrot.val=1 elif Presets.val == 7: buttonreset() yrot.val=2 xmir.val=1 elif Presets.val == 8: buttonreset() ymir.val=1 xmir.val=1 elif Presets.val == 9: buttonreset() ymir.val=1 xmir.val=1 xrim2.val=1 elif Presets.val == 10: buttonreset() xrot.val=1 yrot.val=1 xmir2.val=1 ymir2.val=1 xrot2.val=-1 yrot2.val=-1 elif Presets.val == 11: buttonreset() yrot.val=1 xrot.val=1 dub.val=1 elif Presets.val == 13: buttonreset() el.val=1 elif Presets.val == 14: buttonreset() el.val=2 exrot.val=1 elif Presets.val == 15: buttonreset() mir.val=1 elif Presets.val == 16: buttonreset() mir.val=1 exrot.val=1 elif Presets.val == 17: buttonreset() dub.val = 1 Draw.Redraw(0) if evt == 2: main(0) if evt == 3: main(1) if 3