Skip to content
Snippets Groups Projects
__init__.py 21.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Andrew Hale's avatar
    Andrew Hale committed
    #====================== BEGIN GPL LICENSE BLOCK ======================
    #
    #  This program is free software; you can redistribute it and/or
    #  modify it under the terms of the GNU General Public License
    #  as published by the Free Software Foundation; either version 2
    #  of the License, or (at your option) any later version.
    #
    #  This program is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #  GNU General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with this program; if not, write to the Free Software Foundation,
    #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    #======================= END GPL LICENSE BLOCK ========================
    
    bl_info = {
        "name": "Sapling",
        "author": "Andrew Hale (TrumanBlending)",
    
    Andrew Hale's avatar
    Andrew Hale committed
        "version": (0, 2, 5),
        "blender": (2, 5, 9),
    
    Andrew Hale's avatar
    Andrew Hale committed
        "location": "View3D > Add > Curve",
        "description": ("Adds a parametric tree. The method is presented by "
        "Jason Weber & Joseph Penn in their paper 'Creation and Rendering of "
        "Realistic Trees'."),
        "warning": "",  # used for warning icon and text in addons panel
    
    Andrew Hale's avatar
    Andrew Hale committed
        "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
            "Scripts/Curve/Sapling_Tree",
    
        "tracker_url": "http://projects.blender.org/tracker/"\
            "?func=detail&atid=469&aid=27226&group_id=153",
    
    Andrew Hale's avatar
    Andrew Hale committed
        "category": "Add Curve"}
    
    if "bpy" in locals():
        import imp
        imp.reload(utils)
    else:
        from add_curve_sapling import utils
    
    import bpy
    import time
    import os
    
    #from utils import *
    from mathutils import *
    from math import pi, sin, degrees, radians, atan2, copysign
    from random import random, uniform, seed, choice, getstate, setstate
    from bpy.props import *
    
    from add_curve_sapling.utils import *
    
    #global splitError
    useSet = False
    
    shapeList = [('0', 'Conical (0)', 'Shape = 0'),
                ('1', 'Spherical (1)', 'Shape = 1'),
                ('2', 'Hemispherical (2)', 'Shape = 2'),
                ('3', 'Cylindrical (3)', 'Shape = 3'),
                ('4', 'Tapered Cylindrical (4)', 'Shape = 4'),
                ('5', 'Flame (5)', 'Shape = 5'),
                ('6', 'Inverse Conical (6)', 'Shape = 6'),
                ('7', 'Tend Flame (7)', 'Shape = 7')]
    
    handleList = [('0', 'Auto', 'Auto'),
                    ('1', 'Vector', 'Vector')]
    
    settings = [('0', 'Geometry', 'Geometry'),
                ('1', 'Branch Splitting', 'Branch Splitting'),
                ('2', 'Branch Growth', 'Branch Growth'),
                ('3', 'Pruning', 'Pruning'),
                ('4', 'Leaves', 'Leaves'),
                ('5', 'Armature', 'Armature')]
    
    
    def getPresetpath():
        '''Support user defined scripts directory
           Find the first ocurrence of add_curve_sapling/presets in possible script paths
           and return it as preset path'''
        presetpath = ""
        for p in bpy.utils.script_paths():
            presetpath = os.path.join(p, 'addons', 'add_curve_sapling', 'presets')
            if os.path.exists(presetpath):
                break
        return presetpath
    
    
    class ExportData(bpy.types.Operator):
        '''This operator handles writing presets to file'''
        bl_idname = 'sapling.exportdata'
        bl_label = 'Export Preset'
    
        data = StringProperty()
    
        def execute(self, context):
            # Unpack some data from the input
            data, filename = eval(self.data)
            try:
                # Check whether the file exists by trying to open it.
                f = open(os.path.join(getPresetpath(), filename + '.py'), 'r')
                f.close()
                # If it exists then report an error
                self.report({'ERROR_INVALID_INPUT'}, 'Preset Already Exists')
                return {'CANCELLED'}
            except IOError:
                if data:
                    # If it doesn't exist, create the file with the required data
                    f = open(os.path.join(getPresetpath(), filename + '.py'), 'w')
                    f.write(data)
                    f.close()
                    return {'FINISHED'}
                else:
                    return {'CANCELLED'}
    
    
    class ImportData(bpy.types.Operator):
        '''This operator handles importing existing presets'''
        bl_idname = 'sapling.importdata'
        bl_label = 'Import Preset'
    
        filename = StringProperty()
    
        def execute(self, context):
            # Make sure the operator knows about the global variables
            global settings, useSet
            # Read the preset data into the global settings
            f = open(os.path.join(getPresetpath(), self.filename), 'r')
            settings = f.readline()
            f.close()
            #print(settings)
            settings = eval(settings)
            # Set the flag to use the settings
            useSet = True
            return {'FINISHED'}
    
    
    class PresetMenu(bpy.types.Menu):
        '''Create the preset menu by finding all preset files
        in the preset directory
        '''
        bl_idname = "sapling.presetmenu"
        bl_label = "Presets"
    
        def draw(self, context):
            # Get all the sapling presets
            presets = [a for a in os.listdir(getPresetpath()) if a[-3:] == '.py']
            layout = self.layout
            # Append all to the menu
            for p in presets:
                layout.operator("sapling.importdata", text=p[:-3]).filename = p
    
    
    class AddTree(bpy.types.Operator):
        bl_idname = "curve.tree_add"
    
    Andrew Hale's avatar
    Andrew Hale committed
        bl_options = {'REGISTER', 'UNDO'}
    
    
    Andrew Hale's avatar
    Andrew Hale committed
    
        def update_tree(self, context):
            self.do_update = True
        
        def no_update_tree(self, context):
            self.do_update = False
    
        do_update = BoolProperty(name='Do Update',
            default=True, options={'HIDDEN'})
    
    
    Andrew Hale's avatar
    Andrew Hale committed
        chooseSet = EnumProperty(name='Settings',
            description='Choose the settings to modify',
            items=settings,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default='0', update=no_update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        bevel = BoolProperty(name='Bevel',
            description='Whether the curve is bevelled',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=False, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        prune = BoolProperty(name='Prune',
            description='Whether the tree is pruned',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=False, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        showLeaves = BoolProperty(name='Show Leaves',
            description='Whether the leaves are shown',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=False, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        useArm = BoolProperty(name='Use Armature',
            description='Whether the armature is generated',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=False, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        seed = IntProperty(name='Random Seed',
            description='The seed of the random number generator',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        handleType = IntProperty(name='Handle Type',
            description='The type of curve handles',
            min=0,
            max=1,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        levels = IntProperty(name='Levels',
            description='Number of recursive branches (Levels)',
            min=1,
            max=6,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=3, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        length = FloatVectorProperty(name='Length',
            description='The relative lengths of each branch level (nLength)',
    
    Andrew Hale's avatar
    Andrew Hale committed
            min=0.000001,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=[1, 0.3, 0.6, 0.45],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        lengthV = FloatVectorProperty(name='Length Variation',
            description='The relative length variations of each level (nLengthV)',
            min=0.0,
            default=[0, 0, 0, 0],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        branches = IntVectorProperty(name='Branches',
            description='The number of branches grown at each level (nBranches)',
            min=0,
            default=[50, 30, 10, 10],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        curveRes = IntVectorProperty(name='Curve Resolution',
            description='The number of segments on each branch (nCurveRes)',
            min=1,
            default=[3, 5, 3, 1],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        curve = FloatVectorProperty(name='Curvature',
            description='The angle of the end of the branch (nCurve)',
            default=[0, -40, -40, 0],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        curveV = FloatVectorProperty(name='Curvature Variation',
            description='Variation of the curvature (nCurveV)',
            default=[20, 50, 75, 0],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        curveBack = FloatVectorProperty(name='Back Curvature',
            description='Curvature for the second half of a branch (nCurveBack)',
            default=[0, 0, 0, 0],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        baseSplits = IntProperty(name='Base Splits',
            description='Number of trunk splits at its base (nBaseSplits)',
            min=0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        segSplits = FloatVectorProperty(name='Segment Splits',
            description='Number of splits per segment (nSegSplits)',
            min=0,
            default=[0, 0, 0, 0],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        splitAngle = FloatVectorProperty(name='Split Angle',
            description='Angle of branch splitting (nSplitAngle)',
            default=[0, 0, 0, 0],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        splitAngleV = FloatVectorProperty(name='Split Angle Variation',
            description='Variation in the split angle (nSplitAngleV)',
            default=[0, 0, 0, 0],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        scale = FloatProperty(name='Scale',
            description='The tree scale (Scale)',
            min=0.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=13.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        scaleV = FloatProperty(name='Scale Variation',
            description='The variation in the tree scale (ScaleV)',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=3.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        attractUp = FloatProperty(name='Vertical Attraction',
            description='Branch upward attraction',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        shape = EnumProperty(name='Shape',
            description='The overall shape of the tree (Shape)',
            items=shapeList,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default='7', update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        baseSize = FloatProperty(name='Base Size',
            description='Fraction of tree height with no branches (BaseSize)',
            min=0.0,
            max=1.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        ratio = FloatProperty(name='Ratio',
            description='Base radius size (Ratio)',
            min=0.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.015, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        taper = FloatVectorProperty(name='Taper',
            description='The fraction of tapering on each branch (nTaper)',
            min=0.0,
            max=1.0,
            default=[1, 1, 1, 1],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        ratioPower = FloatProperty(name='Branch Radius Ratio',
            description=('Power which defines the radius of a branch compared to '
            'the radius of the branch it grew from (RatioPower)'),
            min=0.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=1.2, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        downAngle = FloatVectorProperty(name='Down Angle',
            description=('The angle between a new branch and the one it grew '
            'from (nDownAngle)'),
            default=[90, 60, 45, 45],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        downAngleV = FloatVectorProperty(name='Down Angle Variation',
            description='Variation in the down angle (nDownAngleV)',
            default=[0, -50, 10, 10],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        rotate = FloatVectorProperty(name='Rotate Angle',
            description=('The angle of a new branch around the one it grew from '
            '(nRotate)'),
            default=[140, 140, 140, 77],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        rotateV = FloatVectorProperty(name='Rotate Angle Variation',
            description='Variation in the rotate angle (nRotateV)',
            default=[0, 0, 0, 0],
    
    Andrew Hale's avatar
    Andrew Hale committed
            size=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        scale0 = FloatProperty(name='Radius Scale',
            description='The scale of the trunk radius (0Scale)',
            min=0.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=1.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        scaleV0 = FloatProperty(name='Radius Scale Variation',
            description='Variation in the radius scale (0ScaleV)',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.2, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        pruneWidth = FloatProperty(name='Prune Width',
            description='The width of the envelope (PruneWidth)',
            min=0.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        pruneWidthPeak = FloatProperty(name='Prune Width Peak',
            description=('Fraction of envelope height where the maximum width '
            'occurs (PruneWidthPeak)'),
            min=0.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.6, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        prunePowerHigh = FloatProperty(name='Prune Power High',
            description=('Power which determines the shape of the upper portion '
            'of the envelope (PrunePowerHigh)'),
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.5, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        prunePowerLow = FloatProperty(name='Prune Power Low',
            description=('Power which determines the shape of the lower portion '
            'of the envelope (PrunePowerLow)'),
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.001, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        pruneRatio = FloatProperty(name='Prune Ratio',
            description='Proportion of pruned length (PruneRatio)',
            min=0.0,
            max=1.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=1.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        leaves = IntProperty(name='Leaves',
            description='Maximum number of leaves per branch (Leaves)',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=25, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        leafScale = FloatProperty(name='Leaf Scale',
            description='The scaling applied to the whole leaf (LeafScale)',
            min=0.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.17, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        leafScaleX = FloatProperty(name='Leaf Scale X',
            description=('The scaling applied to the x direction of the leaf '
            '(LeafScaleX)'),
            min=0.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=1.0, update=update_tree)
    
        leafShape = leafDist = EnumProperty(name='Leaf Shape',
            description='The shape of the leaves, rectangular are UV mapped',
            items=(('hex', 'Hexagonal', '0'), ('rect', 'Rectangular', '1')),
    
    Andrew Hale's avatar
    Andrew Hale committed
            default='hex', update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        bend = FloatProperty(name='Leaf Bend',
            description='The proportion of bending applied to the leaf (Bend)',
            min=0.0,
            max=1.0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        leafDist = EnumProperty(name='Leaf Distribution',
            description='The way leaves are distributed on branches',
            items=shapeList,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default='4', update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        bevelRes = IntProperty(name='Bevel Resolution',
            description='The bevel resolution of the curves',
            min=0,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        resU = IntProperty(name='Curve Resolution',
            description='The resolution along the curves',
            min=1,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=4, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        handleType = EnumProperty(name='Handle Type',
            description='The type of handles used in the spline',
            items=handleList,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default='1', update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        frameRate = FloatProperty(name='Frame Rate',
            description=('The number of frames per second which can be used to '
            'adjust the speed of animation'),
            min=0.001,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=1, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        windSpeed = FloatProperty(name='Wind Speed',
            description='The wind speed to apply to the armature (WindSpeed)',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=2.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        windGust = FloatProperty(name='Wind Gust',
            description='The greatest increase over Wind Speed (WindGust)',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        armAnim = BoolProperty(name='Armature Animation',
            description='Whether animation is added to the armature',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=False, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
    
        presetName = StringProperty(name='Preset Name',
            description='The name of the preset to be saved',
            default='',
    
    Andrew Hale's avatar
    Andrew Hale committed
            subtype='FILENAME', update=no_update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
        limitImport = BoolProperty(name='Limit Import',
            description='Limited imported tree to 2 levels & no leaves for speed',
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=True, update=no_update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
    
        startCurv = FloatProperty(name='Trunk Starting Angle',
            description=('The angle between vertical and the starting direction '
            'of the trunk'),
            min=0.0,
            max=360,
    
    Andrew Hale's avatar
    Andrew Hale committed
            default=0.0, update=update_tree)
    
    Andrew Hale's avatar
    Andrew Hale committed
    
        @classmethod
        def poll(cls, context):
            return context.mode == 'OBJECT'
    
        def draw(self, context):
    
    
    Andrew Hale's avatar
    Andrew Hale committed
            layout = self.layout
    
    Andrew Hale's avatar
    Andrew Hale committed
            # Branch specs
            #layout.label('Tree Definition')
    
    Thomas Dinges's avatar
    Thomas Dinges committed
            layout.prop(self, 'chooseSet')
    
    Andrew Hale's avatar
    Andrew Hale committed
            if self.chooseSet == '0':
    
    Andrew Hale's avatar
    Andrew Hale committed
                box = layout.box()
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                box.label("Geometry:")
                box.prop(self, 'bevel')
                
    
    Andrew Hale's avatar
    Andrew Hale committed
                row = box.row()
                row.prop(self, 'bevelRes')
                row.prop(self, 'resU')
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                
                box.prop(self, 'handleType')
                box.prop(self, 'shape')
                box.prop(self, 'seed')
                box.prop(self, 'ratio')
                
    
    Andrew Hale's avatar
    Andrew Hale committed
                row = box.row()
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                row.prop(self, 'scale')
                row.prop(self, 'scaleV')
                
    
    Andrew Hale's avatar
    Andrew Hale committed
                row = box.row()
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                row.prop(self, 'scale0')
                row.prop(self, 'scaleV0')
    
    Andrew Hale's avatar
    Andrew Hale committed
    
                # Here we create a dict of all the properties.
                # Unfortunately as_keyword doesn't work with vector properties,
                # so we need something custom. This is it
                data = []
    
    Andrew Hale's avatar
    Andrew Hale committed
                for a, b in (self.as_keywords(ignore=("chooseSet", "presetName", "limitImport", "do_update"))).items():
    
    Andrew Hale's avatar
    Andrew Hale committed
                    # If the property is a vector property then add the slice to the list
                    try:
                        len(b)
                        data.append((a, b[:]))
    
    Andrew Hale's avatar
    Andrew Hale committed
                    # Otherwise, it is fine so just add it
    
    Andrew Hale's avatar
    Andrew Hale committed
                    except:
    
    Andrew Hale's avatar
    Andrew Hale committed
                        data.append((a, b))
                # Create the dict from the list
                data = dict(data)
    
                row = box.row()
                row.prop(self, 'presetName')
                # Send the data dict and the file name to the exporter
                row.operator('sapling.exportdata').data = repr([repr(data),
                                                           self.presetName])
                row = box.row()
                row.menu('sapling.presetmenu', text='Load Preset')
                row.prop(self, 'limitImport')
    
    
    Thomas Dinges's avatar
    Thomas Dinges committed
            elif self.chooseSet == '1':
    
    Andrew Hale's avatar
    Andrew Hale committed
                box = layout.box()
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                box.label("Branch Splitting:")
                box.prop(self, 'levels')
                box.prop(self, 'baseSplits')
                box.prop(self, 'baseSize')
                
                split = box.split()
                
                col = split.column()
    
    Andrew Hale's avatar
    Andrew Hale committed
                col.prop(self, 'branches')
                col.prop(self, 'splitAngle')
                col.prop(self, 'downAngle')
                col.prop(self, 'rotate')
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                
                col = split.column()
                col.prop(self, 'segSplits')
                col.prop(self, 'splitAngleV')
                col.prop(self, 'downAngleV')
    
    Andrew Hale's avatar
    Andrew Hale committed
                col.prop(self, 'rotateV')
    
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                box.prop(self, 'ratioPower')
    
            elif self.chooseSet == '2':
    
    Andrew Hale's avatar
    Andrew Hale committed
                box = layout.box()
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                box.label("Branch Growth:")
                box.prop(self, 'startCurv')
                box.prop(self, 'attractUp')
                
                split = box.split()
                
                col = split.column()
    
    Andrew Hale's avatar
    Andrew Hale committed
                col.prop(self, 'length')
                col.prop(self, 'curve')
                col.prop(self, 'curveBack')
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                
                col = split.column()
                col.prop(self, 'lengthV')
                col.prop(self, 'curveV')
    
    Andrew Hale's avatar
    Andrew Hale committed
                col.prop(self, 'taper')
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                
                box.column().prop(self, 'curveRes')
    
    Thomas Dinges's avatar
    Thomas Dinges committed
            elif self.chooseSet == '3':
    
    Andrew Hale's avatar
    Andrew Hale committed
                box = layout.box()
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                box.label("Pruning:")
                box.prop(self, 'prune')
                box.prop(self, 'pruneRatio')
                box.prop(self, 'pruneWidth')
                box.prop(self, 'pruneWidthPeak')
                
    
    Andrew Hale's avatar
    Andrew Hale committed
                row = box.row()
                row.prop(self, 'prunePowerHigh')
                row.prop(self, 'prunePowerLow')
    
    
    Thomas Dinges's avatar
    Thomas Dinges committed
            elif self.chooseSet == '4':
    
    Andrew Hale's avatar
    Andrew Hale committed
                box = layout.box()
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                box.label("Leaves:")
                box.prop(self, 'showLeaves')
                box.prop(self, 'leafShape')
                box.prop(self, 'leaves')
                box.prop(self, 'leafDist')
                
                row = box.row()
                row.prop(self, 'leafScale')
                row.prop(self, 'leafScaleX')
                
                box.prop(self, 'bend')
    
            elif self.chooseSet == '5':
    
    Andrew Hale's avatar
    Andrew Hale committed
                box = layout.box()
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                box.label("Armature and Animation:")
                
    
    Andrew Hale's avatar
    Andrew Hale committed
                row = box.row()
                row.prop(self, 'useArm')
                row.prop(self, 'armAnim')
    
    Andrew Hale's avatar
    Andrew Hale committed
                row = box.row()
                row.prop(self, 'windSpeed')
                row.prop(self, 'windGust')
    
    Thomas Dinges's avatar
    Thomas Dinges committed
                
                box.prop(self, 'frameRate')
    
    Andrew Hale's avatar
    Andrew Hale committed
    
        def execute(self, context):
            # Ensure the use of the global variables
            global settings, useSet
            start_time = time.time()
            #bpy.ops.ImportData.filename = "quaking_aspen"
            # If we need to set the properties from a preset then do it here
            if useSet:
                for a, b in settings.items():
                    setattr(self, a, b)
                if self.limitImport:
                    setattr(self, 'levels', 2)
                    setattr(self, 'showLeaves', False)
                useSet = False
    
    Andrew Hale's avatar
    Andrew Hale committed
            if not self.do_update:
                return {'PASS_THROUGH'}
    
    Andrew Hale's avatar
    Andrew Hale committed
            addTree(self)
            print("Tree creation in %0.1fs" %(time.time()-start_time))
            return {'FINISHED'}
        
        def invoke(self, context, event):
    #        global settings, useSet
    #        useSet = True
            bpy.ops.sapling.importdata(filename = "quaking_aspen.py")
            return self.execute(context)
    
    
    def menu_func(self, context):
        self.layout.operator(AddTree.bl_idname, text="Add Tree", icon='PLUGIN')
    
    
    def register():
        bpy.utils.register_module(__name__)
    
        bpy.types.INFO_MT_curve_add.append(menu_func)
    
    
    def unregister():
        bpy.utils.unregister_module(__name__)
    
        bpy.types.INFO_MT_curve_add.remove(menu_func)
    
    if __name__ == "__main__":
    
    Guillermo S. Romero's avatar
    Guillermo S. Romero committed
        register()