[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