# Space Colonization Tree

Currently im trying to make an addon for the Space Colonization Algorithm in Blender. At the moment i only have a skeleton as a tree. Does anybody have an idea on how to thicken the tree so it does look somewhat realistic? I already tried the skin modifier, but that makes everywhere the same thickness and thinning it down by hand is not a possibility. And the bevel modifier behaves strangely since i probably have too many points. Thanks, Nebeig edit: I tried it with the following code:

import bpy
radius = 0.4

obj = bpy.data.objects['Tree']

bpy.ops.object.modifier_add(type='SKIN')

for v in obj.data.skin_vertices.data:
radius -= 0.00025
v.radius = (radius,radius)

print(v.radius[:])


but blender chrashes when i try to execute the script.

    from random import randint, random, uniform
from copy import copy, deepcopy

def getDistance(p0, p1):
return sqrt((p0 - p1)**2 + (p0 - p1)**2 + (p0 -
p1)**2)

# importiert von https://blender.stackexchange.com/questions/5898/how-can-i-
create-a-cylinder-linking-two-points-with-python

class Tree:
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
bl_label = 'Tools Tab Label'
bl_context = 'objectmode'
bl_category = 'SC'

def __init__(self):
# Vektor operationen

def div(x,y):
return(x/y, x/y, x/y)

def sub(x,y):
return(x-y, x-y, x-y)

def normieren(x,y):
länge = sqrt(x**2 + x**2 + x**2)
return((x/länge + x/länge+ x/länge)*y)

def length_squared(u):
return sum([a ** 2 for a in u])

def add(u, v):
return [a + b for a, b in zip(u, v)]

def norm(u):
return setlength(u, 0.5)

def scale_by_scalar(u, scalar):
return [a * scalar for a in u]

def length(u):
return math.sqrt(length_squared(u))

def setlength(u, l):
return scale_by_scalar(u, l / length(u))

branches = []
leaves = []
verts = ()
closeEnough = 0 # False

#leaves generieren
for i in range(0,150):
leaves.append(Leaf((uniform(-4.0,4.0),uniform(-4.0,4.0),uniform(4.0,9.0)),0))
#bpy.ops.mesh.primitive_uv_sphere_add(size=0.1, location=leaves[i].pos)
i =+ 1

#Stamm machen
root = Branch(None,(0,0,0),(0,0,0.5))
branches.append(root)
current = root

max_dist = 3
min_dist = 1
while closeEnough == 0: # False
for i in range (len(leaves)):
g = 0
g = getDistance(current.pos, leaves[i].pos)
#print(g)
if (g < max_dist):
print('schlaufe 1')
closeEnough = 1
if (closeEnough == 0):
print('         schlaufe 2          ')
nextPos = tuple(add(branches[i].pos,branches[i].dir))
branch = Branch(i,nextPos,branches[i].dir)
current = branch
branches.append(current)
if (g > 100):
break

#Der eigentliche Algorithmus
def grow(self):
self.record = 100000
for i in range(len(leaves)):
leaf = leaves[i]
closestBranch = None
self.closestDir = None

#Den nächsten Ast bestimmen
for j in range(len(branches)):
#print(j)
branch = branches[j]
dir = sub(leaf.pos ,branch.pos)
d = length(dir)
#print(d)
if (d < min_dist):
leaf.reached()
break
#elif(d > max_dist):
elif (closestBranch == None or d < self.record):
closestBranch = branch
self.record = d

#Dessen Richtung bestimmen
if (closestBranch is not None):
newDir = tuple(sub(leaf.pos, closestBranch.pos))
newDirnormed = norm(newDir)
#print(newDir)
closestBranch.dir = tuple(add(closestBranch.dir,
newDirnormed))
closestBranch.count += 1

#alle Blätter entfernen die erreicht wurden
for i in reversed(range(len(leaves))):
if (leaves[i].erreicht == 1):
del(leaves[i])

branchcopy = deepcopy(branches)
#print(branches.dir)
for i in reversed(range(len(branches))):
branch = branches[i]
#print(branch.count)
if (branch.count > 0):
branch.dir = tuple(div(branch.dir,branch.count))
newPos = tuple(add(branch.pos,branch.dir))
newB = Branch(i, newPos, branch.dir)
branches.append(newB)
branch.reset()

for i in range(70):
grow(self)

# this assumes all vertex positions are unique (= do not overlap)
# create a mapping from vertex position to vertex index
verts = {b.pos:i for i,b in enumerate(branches)}
# create vertex pairs as edge by locating vert index based on
coordinates
edges = [ (verts[b.pos],verts[branches[b.parent].pos])for b in branches
if b.parent is not None]
# replace vertex mapping by simple list of coordinates
verts = [b.pos for b in branches]

mesh = bpy.data.meshes.new("tree_mesh")
mesh.from_pydata(verts, edges, faces=[])
mesh.update()

obj = bpy.data.objects.new("Tree", mesh)

scene = bpy.context.scene
scene.objects.link(obj)
#remove doubles muss man noch machen

obj = bpy.data.objects['Tree']
for v in obj.vertices:
v.select = True
bpy.ops.transform.skin_resize(value=(0.695461, 0.695461, 0.695461))
v.deselect = True

tree= Tree()

• If you add the skin modifier to your mesh, it will create a 'skin_vertices' object in it, where you can access to the radius of the vertices... For example: bpy.data.objects['Obj'].data.skin_vertices[''].data.radius = (1.0, 1.0) – Secrop Jul 20 '18 at 10:56
• Probably something wrong with your mesh... that script works ok here. Post your blend file for inspection. – Secrop Jul 20 '18 at 14:17

## 2 Answers

I resolved the problem by setting the name of the radius variable to something different than radius.

Try the Sapling Tree Gen add-on. You should have it in your copy of Blender and activate it.