[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2234] branches: First commit for a sapling rewrite to improve speed an stability
Andrew Hale
TrumanBlending at gmail.com
Mon Aug 8 09:44:24 CEST 2011
Revision: 2234
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2234
Author: trumanblending
Date: 2011-08-08 07:44:23 +0000 (Mon, 08 Aug 2011)
Log Message:
-----------
First commit for a sapling rewrite to improve speed an stability
Added Paths:
-----------
branches/sapling_rewrite/
branches/sapling_rewrite/sapling_rewrite.py
Added: branches/sapling_rewrite/sapling_rewrite.py
===================================================================
--- branches/sapling_rewrite/sapling_rewrite.py (rev 0)
+++ branches/sapling_rewrite/sapling_rewrite.py 2011-08-08 07:44:23 UTC (rev 2234)
@@ -0,0 +1,1340 @@
+import bpy
+import time
+import os
+from collections import deque
+from random import choice, random, uniform, seed
+from mathutils import Vector, Matrix
+from math import pi, degrees, radians, cos, atan2, copysign, sin
+from bpy.props import *
+
+
+rot_matrix = Matrix.Rotation
+xAxis = Vector((1, 0, 0))
+yAxis = Vector((0, 1, 0))
+zAxis = Vector((0, 0, 1))
+useSet = False
+
+
+def spread_mat(dec):
+ rand_sign = choice((-1, 1))
+ angle = rand_sign * radians(20 + 0.75 * random() *
+ (30 + abs(90 - degrees(dec))))
+ return rot_matrix(angle, 3, 'Z')
+
+
+class Tree:
+ __slots__ = ('levels', 'num_levels', 'shape', 'leaves', 'scaleTree',
+ 'baseSize', 'trunkLength', 'trunkRadius', 'ratioPower',
+ 'baseLength', 'num_leaves', 'leafScale', 'leafScaleX',
+ 'leafBend', 'showLeaves', 'pruneWidth', 'pruneWidthPeak',
+ 'prunePowerHigh', 'prunePowerLow')
+
+ def __init__(self,
+ levels = 3,
+ length = (1, 0.3, 0.6, 0.45),
+ lengthV = (0, 0, 0, 0),
+ branches = (0, 50, 30, 10),
+ curveRes = (2, 5, 3, 1),
+ curve = (0, radians(-40), radians(-40), 0),
+ curveV = (radians(20), radians(50), radians(75), 0),
+ curveBack = (0, 0, 0, 0),
+ baseSplits = 0,
+ segSplits = (0, 0, 0, 0),
+ splitAngle = (radians(30), 0, 0, 0),
+ splitAngleV = (0, 0, 0, 0),
+ scale = 13,
+ scaleV = 3,
+ attractionUp = 0.5,
+ shape = 7,
+ baseSize = 0.4,
+ ratio = 0.015,
+ taper = (1, 1, 1, 1),
+ ratioPower = 1.2,
+ downAngle = (radians(90), radians(60), radians(45), radians(45)),
+ downAngleV = (0, radians(-50), radians(10), radians(10)),
+ rotate = (radians(140), radians(140), radians(140), radians(77)),
+ rotateV = (0, 0, 0, 0),
+ scale0 = 1.0,
+ scale0V = 0.2,
+ showLeaves = True,
+ leaves = 25,
+ leafScale = 0.17,
+ leafScaleX = 0.8,
+ leafBend = 0.2,
+ pruneWidth = 0.4,
+ pruneWidthPeak = 0.6,
+ prunePowerHigh = 0.5,
+ prunePowerLow = 0.001):
+
+ self.showLeaves = showLeaves
+ self.num_leaves = leaves
+ self.leafScale = leafScale
+ self.leafScaleX = leafScaleX
+ self.leafBend = leafBend
+ self.ratioPower = ratioPower
+ self.scaleTree = scale + uniform(-scaleV, scaleV)
+ self.trunkLength = self.scaleTree * length[0]
+ self.baseSize = baseSize
+ self.baseLength = self.trunkLength * baseSize * self.scaleTree
+ self.trunkRadius = (self.trunkLength * ratio *
+ (scale0 + uniform(-scale0V, scale0V)))
+ self.shape = int(shape)
+ self.num_levels = levels
+ self.levels = deque()
+ self.leaves = deque()
+
+
+ self.pruneWidth = pruneWidth
+ self.pruneWidthPeak = pruneWidthPeak
+ self.prunePowerHigh = prunePowerHigh
+ self.prunePowerLow = prunePowerLow
+
+ # Generate each of the levels for the tree with the required properties
+ for i in range(levels):
+ tmpLevel = Level()
+ tmpLevel.index = i
+ i = min(3, i)
+ if i == 0:
+ tmpLevel.baseSplits = baseSplits
+ tmpLevel.length = length[i]
+ tmpLevel.lengthV = lengthV[i]
+ tmpLevel.nextLength = length[min(3, i + 1)]
+ tmpLevel.nextLengthV = lengthV[min(3, i + 1)]
+ tmpLevel.num_branches = branches[min(3, i + 1)]
+ tmpLevel.curveRes = curveRes[i]
+ tmpLevel.nextCurveRes = curveRes[min(3, i + 1)]
+ tmpLevel.curve = curve[i]
+ tmpLevel.curveV = curveV[i]
+ tmpLevel.curveBack = curveBack[i]
+ tmpLevel.segSplits = segSplits[i]
+ tmpLevel.splitAngle = splitAngle[i]
+ tmpLevel.splitAngleV = splitAngleV[i]
+ tmpLevel.attractionUp = attractionUp
+ tmpLevel.taper = taper[i]
+ tmpLevel.downAngle = downAngle[min(3, i + 1)]
+ tmpLevel.downAngleV = downAngleV[min(3, i + 1)]
+ tmpLevel.rotate = rotate[i]
+ tmpLevel.rotateV = rotateV[i]
+ self.levels.append(tmpLevel)
+
+
+ def grow(self, level, node_num):
+ '''This function grows the "level" of the tree at the node_num-th node.
+ All nodes within a level are added here.'''
+
+ # Loop over all the branches in the level
+ for bIdx, b in enumerate(level.branches):
+
+ # Initialise a deque to store any branches that are added during
+ # growth so that the list we're looping over doesn't change
+ new_twigs = deque()
+ add_twig = new_twigs.append
+
+ # Get the final twig of the branch
+ oldTwig = b.twigs[-1]
+
+ # Loop over all twigs in the branch
+ for twIdx, tw in enumerate(b.twigs):
+
+ # Since a twig can have less nodes than the branch maximum
+ # we need to find the position in this twig
+ twig_node_idx = node_num - (level.curveRes + 1 - tw.nodes)
+
+ # Get the final node in the twig
+ oldNode = tw.twig_nodes[twig_node_idx - 1]
+
+ # Determine the number of splits at this node
+ num_splits = level.num_splits()
+
+ # If this is the last node, then no splits can be done
+ if node_num == level.curveRes:
+ num_splits = 0
+
+ # Loop over all the splits which have been created
+ for i in range(num_splits):
+
+ # Add a new Twig for each split
+ tmpTwig = Twig(level.curveRes - oldNode.index,
+ oldTwig.extra_curve,
+ 'B' +
+ str(level.index) +
+ str(bIdx) +
+ str(twIdx) +
+ str(node_num)
+ )
+
+ # Make a new node and shift it
+ tmpNode = TwigNode(oldNode)
+ tmpNode.co += b.seg_length * tmpNode.dir
+
+ # Create a new vector for the growth direction and store
+ # the method to rotate it
+ dir = zAxis.copy()
+ dirRot = dir.rotate
+
+ # Do the split rotation to spread new nodes
+ dirRot(level.split_mat(tmpNode.dec, tmpTwig))
+
+ # Do the spriral rotation so new nodes don't go
+ # the same way
+ rotMat = rot_matrix(2 * pi * (i + 1) / num_splits, 3, 'Z')
+
+ # Rotate dir by spiral, quat to get original dir,
+ # and spread
+ dirRot(rotMat)
+ dirRot(level.curve_mat(tmpNode.index, tmpTwig))
+ dirRot(tmpNode.quat)
+
+ # Set the direction of growth
+ tmpNode.dir = dir
+
+ # Update quat, dec, ori
+ tmpNode.update()
+
+ # Spread the direction of growth
+ dirRot(spread_mat(tmpNode.dec))
+
+ # Update again
+ tmpNode.update()
+
+ # If this is not the trunk or main branch then add the
+ # attraction up curvature
+ if level.index > 1:
+
+ tmpAxis = xAxis.copy()
+ tmpAxis.rotate(tmpNode.quat)
+
+ # Attraction up rotation
+ dirRot(level.attract_up_mat(tmpNode.dec, tmpNode.ori, tmpAxis))
+
+ # Update again
+ tmpNode.update()
+
+ # Set the node as the first of the twig
+ tmpTwig.twig_nodes[0] = tmpNode
+
+ # Add the twig to the new list
+ add_twig(tmpTwig)
+
+ # Make a new node and shift it
+ tmpNode = TwigNode(oldNode)
+ tmpNode.co += b.seg_length * tmpNode.dir
+
+ # Create a new vector for the growth direction and store
+ # the method to rotate it
+ dir = zAxis.copy()
+ dirRot = dir.rotate
+
+ # If there are splits, do the rotation
+ if num_splits != 0:
+ # Do the split rotation to spread new nodes
+ dirRot(level.split_mat(tmpNode.dec, tw))
+
+ # Do the curvature rotation
+ dirRot(level.curve_mat(tmpNode.index, tw))
+
+ # Rotate dir by quat to get original dir,
+ # and spread
+ dirRot(tmpNode.quat)
+
+ tmpNode.dir = dir
+
+ # Update quat, dec, ori
+ tmpNode.update()
+
+ if num_splits != 0:
+ dirRot(spread_mat(tmpNode.dec))
+
+ # Update quat, dec, ori
+ tmpNode.update()
+
+ if level.index > 1:
+
+ tmpAxis = xAxis.copy()
+ tmpAxis.rotate(tmpNode.quat)
+
+ # Attraction up rotation
+ dirRot(level.attract_up_mat(tmpNode.dec, tmpNode.ori, tmpAxis))
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list