Mar 022011
This is a simple script I wrote that generates meshes using DLA.
I made a little demo animation where I ran the mesh as a cloth sim.
print("-----GO-----")
import bpy
import random
from math import sin, cos, pi, sqrt
from mathutils import Vector
HardRadius = 2
RandWalkRange = .15
StickThresh = .15 #distance threshold to accrete
MaxVerts = 100 #stop when this many verts have been added
seedLOC = Vector((0.0,0.0,0.0))
D3 = True
mname = "DLAtest"
def brownian():
dx = random.gauss(0, RandWalkRange)
dy = random.gauss(0, RandWalkRange)
dz = random.gauss(0, RandWalkRange)
return Vector((dx, dy, dz))
####returns a new wanderer on sphere
def newWanderer():
randAngleA = random.uniform(0,2*pi)
randAngleB = random.uniform(0,2*pi)
x = HardRadius * sin(randAngleA) * cos(randAngleB)
y = HardRadius * sin(randAngleA) * sin(randAngleB)
z = HardRadius * cos(randAngleA)
return Vector((x, y, z))
def dist(A, B):
xd = B.x-A.x
yd = B.y-A.y
zd = B.z-A.z
return sqrt(xd*xd + yd*yd + zd*zd)
def wanderLoop(ob):
wand = newWanderer()
mmesh = ob.data
while len(mmesh.vertices) < MaxVerts:
brown = brownian()
wand.x += brown.x
wand.y += brown.y
if D3: wand.z += brown.z
else: wand.z = 0
if abs(wand.x) > HardRadius or
abs(wand.y) > HardRadius or
abs(wand.z) > HardRadius:
wand = newWanderer()
for vert in range(len(mmesh.vertices)):
dpt = dist(wand, mmesh.vertices[vert].co)
dZ = dist(wand, seedLOC)
if dpt < StickThresh:
st = str(len(mmesh.vertices)+1) + " of " + str(MaxVerts) + " has been assimilated"
print(st, dpt)
addPoint(ob, wand, vert)
wand = newWanderer()
pass
####Object, point to add, index of vert to connect to (None is -1)
def addPoint(ob, pt, conni):
mmesh = ob.data
mmesh.vertices.add(1)
vcounti = len(mmesh.vertices)-1
mmesh.vertices[vcounti].co = [pt.x, pt.y, pt.z]
if conni > -1:
mmesh.edges.add(1)
ecounti = len(mmesh.edges)-1
mmesh.edges[ecounti].vertices = [conni, vcounti]
def newDLAMesh(mname):
mmesh = bpy.data.meshes.new(mname)
omesh = bpy.data.objects.new(mname, mmesh)
bpy.context.scene.objects.link(omesh)
addPoint(omesh, seedLOC, -1)
return omesh
ob = newDLAMesh("testDLA")
wanderLoop(ob)
Man this site is great, thanks for sharing all this material! I hope you donĀ“t mind, but I’ll be doing a post on my blog about your site.. Congrats and thanks again for sharing.
Very cool, Thanks!
I figured it out. While piknog around for an update function I found out how to set a key for the energy button. To set a key for the lamps energy you do the following: bpy.data.lamps[‘Lamp’].keyframe_insert(data_path = energy )I figured out the data path by right clicking on the energy button and clicking Copy Data Path So I loop through the frames setting a key on each frame then it was just a matter of playing the animation. Hovering over the play button showed that was as simple as doing this:bpy.ops.screen.animation_play()Here is my final code. (It’s probably going to mess up the identation)import bpyimport randomframe = 0endframe = 30bpy.ops.anim.change_frame(frame = frame) # make sure we are at frame zerofor i in range(frame,endframe+1): # add one because range doesn’t include last number # For loop sets random energy keyframes for Lamp’ bpy.data.lamps[‘Lamp’].energy = random.random() bpy.data.lamps[‘Lamp’].keyframe_insert(data_path = energy ) bpy.ops.anim.change_frame(frame = frame) frame = frame + 1bpy.ops.anim.change_frame(frame = 0) # make sure we are at frame zerobpy.ops.screen.animation_play()I ended up not needing the time module after all. I learned a lot from doing this!