Michel Anders michel.anders at inter.nl.net
Thu Jul 25 17:20:23 CEST 2013

```Revision: 4638
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=4638
Author:   varkenvarken
Date:     2013-07-25 15:20:22 +0000 (Thu, 25 Jul 2013)
Log Message:
-----------
made bl_info url point to correct wiki page

Modified Paths:
--------------

===================================================================
@@ -19,922 +19,952 @@
#
# ##### END GPL LICENSE BLOCK #####

+# <pep8 compliant>
+
bl_info = {
-	"name": "SCA Tree Generator",
-	"author": "michel anders (varkenvarken)",
-	"version": (0, 0, 8),
-	"blender": (2, 66, 0),
-	"location": "View3D > Add > Mesh",
-	"description": "Adds a tree created with the space colonization algorithm starting at the 3D cursor",
-	"warning": "",
-	"wiki_url": "https://github.com/varkenvarken/spacetree/wiki",
-	"tracker_url": "",
+    "name": "SCA Tree Generator",
+    "author": "michel anders (varkenvarken)",
+    "version": (0, 1, 0),
+    "blender": (2, 66, 0),
+    "location": "View3D > Add > Mesh",
+    "description": "Adds a tree created with the space colonization algorithm starting at the 3D cursor",
+    "warning": "",
+    "tracker_url": "",

from time import time
-from random import random,gauss
+from random import random, gauss
from functools import partial
-from math import sin,cos
+from math import sin, cos

import bpy
from bpy.props import FloatProperty, IntProperty, BoolProperty, EnumProperty
-from mathutils import Vector,Euler,Matrix,Quaternion
+from mathutils import Vector, Euler, Matrix, Quaternion

-from .simplefork import simplefork, simplefork2, quadfork, bridgequads # simple skinning algorithm building blocks
-from .sca import SCA, Branchpoint # the core class that implements the space colonization algorithm and the definition of a segment
+from .simplefork import simplefork, simplefork2, quadfork, bridgequads  # simple skinning algorithm building blocks
+from .sca import SCA, Branchpoint  # the core class that implements the space colonization algorithm and the definition of a segment
from .timer import Timer

+
def availableGroups(self, context):
-	return [(name, name, name, n) for n,name in enumerate(bpy.data.groups.keys())]
+    return [(name, name, name, n) for n, name in enumerate(bpy.data.groups.keys())]

+
def availableGroupsOrNone(self, context):
-	groups = [ ('None', 'None', 'None', 1) ]
-	return groups + [(name, name, name, n+1) for n,name in enumerate(bpy.data.groups.keys())]
+    groups = [('None', 'None', 'None', 1)]
+    return groups + [(name, name, name, n + 1) for n, name in enumerate(bpy.data.groups.keys())]

+
def availableObjects(self, context):
-	return [(name, name, name, n+1) for n,name in enumerate(bpy.data.objects.keys())]
+    return [(name, name, name, n + 1) for n, name in enumerate(bpy.data.objects.keys())]

-def ellipsoid(r=5,rz=5,p=Vector((0,0,8)),taper=0):
-	r2=r*r
-	z2=rz*rz
-	if rz>r : r = rz
-	while True:
-		x = (random()*2-1)*r
-		y = (random()*2-1)*r
-		z = (random()*2-1)*r
-		f = (z+r)/(2*r)
-		f = 1 + f*taper if taper>=0 else (1-f)*-taper
-		if f*x*x/r2+f*y*y/r2+z*z/z2 <= 1:
-			yield p+Vector((x,y,z))

-def pointInsideMesh(pointrelativetocursor,ob):
-	mat = ob.matrix_world.inverted()
-	orig = mat*(pointrelativetocursor+bpy.context.scene.cursor_location)
-	count = 0
-	axis=Vector((0,0,1))
-	while True:
-		location,normal,index = ob.ray_cast(orig,orig+axis*10000.0)
-		if index == -1: break
-		count += 1
-		orig = location + axis*0.00001
-	if count%2 == 0:
-		return False
-	return True
-
-def ellipsoid2(rxy=5,rz=5,p=Vector((0,0,8)),surfacebias=1,topbias=1):
-	while True:
-		phi = 6.283*random()
-		theta = 3.1415*(random()-0.5)
-		r = random()**(surfacebias/2)
-		x = r*rxy*cos(theta)*cos(phi)
-		y = r*rxy*cos(theta)*sin(phi)
-		st=sin(theta)
-		st = (((st+1)/2)**topbias)*2-1
-		z = r*rz*st
-		#print(">>>%.2f %.2f %.2f "%(x,y,z))
-		m = p+Vector((x,y,z))
-		reject = False
-		for ob in bpy.context.selected_objects:
-			# probably we should check if each object is a mesh
-			if pointInsideMesh(m,ob) :
-				reject = True
-				break
-		if not reject:
-			yield m
+def ellipsoid(r=5, rz=5, p=Vector((0, 0, 8)), taper=0):
+    r2 = r * r
+    z2 = rz * rz
+    if rz > r:
+        r = rz
+    while True:
+        x = (random() * 2 - 1) * r
+        y = (random() * 2 - 1) * r
+        z = (random() * 2 - 1) * r
+        f = (z + r) / (2 * r)
+        f = 1 + f * taper if taper >= 0 else (1 - f) * -taper
+        if f * x * x / r2 + f * y * y / r2 + z * z / z2 <= 1:
+            yield p + Vector((x, y, z))

+
+def pointInsideMesh(pointrelativetocursor, ob):
+    mat = ob.matrix_world.inverted()
+    orig = mat * (pointrelativetocursor + bpy.context.scene.cursor_location)
+    count = 0
+    axis = Vector((0, 0, 1))
+    while True:
+        location, normal, index = ob.ray_cast(orig, orig + axis * 10000.0)
+        if index == -1:
+            break
+        count += 1
+        orig = location + axis * 0.00001
+    if count % 2 == 0:
+        return False
+    return True
+
+
+def ellipsoid2(rxy=5, rz=5, p=Vector((0, 0, 8)), surfacebias=1, topbias=1):
+    while True:
+        phi = 6.283 * random()
+        theta = 3.1415 * (random() - 0.5)
+        r = random() ** (surfacebias / 2)
+        x = r * rxy * cos(theta) * cos(phi)
+        y = r * rxy * cos(theta) * sin(phi)
+        st = sin(theta)
+        st = (((st + 1) / 2) ** topbias) * 2 - 1
+        z = r * rz * st
+        #print(">>>%.2f %.2f %.2f "%(x,y,z))
+        m = p + Vector((x, y, z))
+        reject = False
+        for ob in bpy.context.selected_objects:
+            # probably we should check if each object is a mesh
+            if pointInsideMesh(m, ob):
+                reject = True
+                break
+        if not reject:
+            yield m
+
+
def halton3D(index):
-	"""
-	return a quasi random 3D vector R3 in [0,1].
-	each component is based on a halton sequence.
-	quasi random is good enough for our purposes and is
-	more evenly distributed then pseudo random sequences.
-	See en.m.wikipedia.org/wiki/Halton_sequence
-	"""
+    """
+    return a quasi random 3D vector R3 in [0,1].
+    each component is based on a halton sequence.
+    quasi random is good enough for our purposes and is
+    more evenly distributed then pseudo random sequences.
+    See en.m.wikipedia.org/wiki/Halton_sequence
+    """

-	def halton(index, base):
-		result=0
-		f=1.0/base
-		I=index
-		while I>0:
-			result += f*(I%base)
-			I=int(I/base)
-			f/=base
-		return result
-	return Vector((halton(index,2),halton(index,3),halton(index,5)))
+    def halton(index, base):
+        result = 0
+        f = 1.0 / base
+        I = index
+        while I > 0:
+            result += f * (I % base)
+            I = int(I / base)
+            f /= base
+        return result
+    return Vector((halton(index, 2), halton(index, 3), halton(index, 5)))

+
def insidegroup(pointrelativetocursor, group):
-	if bpy.data.groups.find(group)<0 : return False
-	for ob in bpy.data.groups[group].objects:
-		if pointInsideMesh(pointrelativetocursor,ob):
-			return True
-	return False
+    if bpy.data.groups.find(group) < 0:
+        return False
+    for ob in bpy.data.groups[group].objects:
+        if pointInsideMesh(pointrelativetocursor, ob):
+            return True
+    return False

-		shadowgroup = None # safeguard otherwise every marker would be rejected
-	nocrowngroup = bpy.data.groups.find(crowngroup)<0
-	index=100+seed
-	nmarkers=0
-	nyield=0
-	while True:
-		nmarkers+=1
-		v = halton3D(index)
-		v[0] *= size[0]
-		v[1] *= size[1]
-		v[2] *= size[2]
-		v+=pointrelativetocursor
-		index+=1
-		insidecrown = nocrowngroup or insidegroup(v,crowngroup)
-		# if shadowgroup overlaps all or a significant part of the crowngroup
-		# no markers will be yielded and we would be in an endless loop.
-		# so if we yield too few correct markers we start yielding them anyway.
-		lowyieldrate = (nmarkers>200) and (nyield/nmarkers < 0.01)
-		if (insidecrown and outsideshadow) or lowyieldrate:
-			nyield+=1
-			yield v
-
+
+def groupdistribution(crowngroup, shadowgroup=None, seed=0, size=Vector((1, 1, 1)), pointrelativetocursor=Vector((0, 0, 0))):
+        shadowgroup = None  # safeguard otherwise every marker would be rejected
+    nocrowngroup = bpy.data.groups.find(crowngroup) < 0
+    index = 100 + seed
+    nmarkers = 0
+    nyield = 0
+    while True:
+        nmarkers += 1
+        v = halton3D(index)
+        v[0] *= size[0]
+        v[1] *= size[1]
+        v[2] *= size[2]
+        v += pointrelativetocursor
+        index += 1
+        insidecrown = nocrowngroup or insidegroup(v, crowngroup)
+        # if shadowgroup overlaps all or a significant part of the crowngroup
+        # no markers will be yielded and we would be in an endless loop.
+        # so if we yield too few correct markers we start yielding them anyway.
+        lowyieldrate = (nmarkers > 200) and (nyield / nmarkers < 0.01)
+        if (insidecrown and outsideshadow) or lowyieldrate:
+            nyield += 1
+            yield v
+
+
def groupExtends(group):
-	"""
-	return a size,minimum tuple both Vector elements, describing the size and position
-	of the bounding box in world space that encapsulates all objects in a group.
-	"""
-	bb=[]
-	if bpy.data.groups.find(group) >=0 :
-		for ob in bpy.data.groups[group].objects:
-			rot = ob.matrix_world.to_quaternion()
-			scale = ob.matrix_world.to_scale()
-			translate = ob.matrix_world.translation

@@ Diff output truncated at 10240 characters. @@
```