Update sapling tree gen: T46559 major rewrite

This commit is contained in:
Brendon Murphy 2016-04-28 12:36:09 +10:00
parent fe34f82e70
commit c3a6d9132a
Notes: blender-bot 2023-02-14 19:52:05 +01:00
Referenced by issue #46559, improved sapling tree generator (Release Ahoy)
12 changed files with 1811 additions and 581 deletions

View File

@ -17,20 +17,15 @@
#======================= END GPL LICENSE BLOCK ========================
bl_info = {
"name": "Sapling",
"author": "Andrew Hale (TrumanBlending)",
"version": (0, 2, 6),
"blender": (2, 73, 0),
"name": "Sapling Tree Gen",
"author": "Andrew Hale (TrumanBlending), Aaron Buchler",
"version": (0, 3, 2),
"blender": (2, 77, 0),
"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": "",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
"Scripts/Curve/Sapling_Tree",
"category": "Add Curve",
}
"category": "Add Curve"}
if "bpy" in locals():
import importlib
@ -41,8 +36,10 @@ else:
import bpy
import time
import os
import ast
#import cProfile
#from utils import *
from mathutils import *
from math import pi, sin, degrees, radians, atan2, copysign
from random import random, uniform, seed, choice, getstate, setstate
@ -50,7 +47,6 @@ from bpy.props import *
from add_curve_sapling.utils import *
#global splitError
useSet = False
shapeList = [('0', 'Conical (0)', 'Shape = 0'),
@ -62,28 +58,74 @@ shapeList = [('0', 'Conical (0)', 'Shape = 0'),
('6', 'Inverse Conical (6)', 'Shape = 6'),
('7', 'Tend Flame (7)', 'Shape = 7')]
shapeList3 = [('0', 'Conical', ''),
('6', 'Inverse Conical', ''),
('1', 'Spherical', ''),
('2', 'Hemispherical', ''),
('3', 'Cylindrical', ''),
('4', 'Tapered Cylindrical', ''),
('10', 'Inverse Tapered Cylindrical', ''),
('5', 'Flame', ''),
('7', 'Tend Flame', ''),
('8', 'Custom Shape', '')]
shapeList4 = [('0', 'Conical', ''),
('6', 'Inverse Conical', ''),
('1', 'Spherical', ''),
('2', 'Hemispherical', ''),
('3', 'Cylindrical', ''),
('4', 'Tapered Cylindrical', ''),
('10', 'Inverse Tapered Cylindrical', ''),
('5', 'Flame', ''),
('7', 'Tend Flame', '')]
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')]
('1', 'Branch Radius', 'Branch Radius'),
('2', 'Branch Splitting', 'Branch Splitting'),
('3', 'Branch Growth', 'Branch Growth'),
('4', 'Pruning', 'Pruning'),
('5', 'Leaves', 'Leaves'),
('6', 'Armature', 'Armature'),
('7', 'Animation', 'Animation')]
branchmodes = [("original", "Original", "rotate around each branch"),
("rotate", "Rotate", "evenly distribute branches to point outward from center of tree"),
("random", "Random", "choose random point")]
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
#presetpath = ""
#for p in bpy.utils.script_paths():
# presetpath = os.path.join(p, 'addons', 'add_curve_sapling_3', 'presets')
# if os.path.exists(presetpath):
# break
#return presetpath
# why not just do this
script_file = os.path.realpath(__file__)
directory = os.path.dirname(script_file)
directory = os.path.join(directory, "presets")
return directory
def getPresetpaths():
"""Return paths for both local and user preset folders"""
userDir = os.path.join(bpy.utils.script_path_user(), 'presets', 'operator', 'add_curve_sapling')
if os.path.isdir(userDir):
pass
else:
os.makedirs(userDir)
script_file = os.path.realpath(__file__)
directory = os.path.dirname(script_file)
localDir = os.path.join(directory, "presets")
return (localDir, userDir)
class ExportData(bpy.types.Operator):
"""This operator handles writing presets to file"""
@ -94,24 +136,46 @@ class ExportData(bpy.types.Operator):
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')
data, filename, overwrite = eval(self.data)
# try:
# # Check whether the file exists by trying to open it.
# f = open(os.path.join(getPresetpaths()[1], 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(getPresetpaths()[1], filename + '.py'), 'w')
# f.write(data)
# f.close()
# return {'FINISHED'}
# else:
# return {'CANCELLED'}
fpath1 = os.path.join(getPresetpaths()[0], filename + '.py')
fpath2 = os.path.join(getPresetpaths()[1], filename + '.py')
if os.path.exists(fpath1):
# If it exists in built-in presets then report an error
self.report({'ERROR_INVALID_INPUT'}, 'Can\'t have same name as built-in preset')
return {'CANCELLED'}
except IOError:
elif (not os.path.exists(fpath2)) or (os.path.exists(fpath2) and overwrite):
#if (it does not exist) or (exists and overwrite) then write file
if data:
# If it doesn't exist, create the file with the required data
f = open(os.path.join(getPresetpath(), filename + '.py'), 'w')
f = open(os.path.join(getPresetpaths()[1], filename + '.py'), 'w')
f.write(data)
f.close()
return {'FINISHED'}
else:
return {'CANCELLED'}
else:
# If it exists then report an error
self.report({'ERROR_INVALID_INPUT'}, 'Preset Already Exists')
return {'CANCELLED'}
class ImportData(bpy.types.Operator):
"""This operator handles importing existing presets"""
@ -124,40 +188,78 @@ class ImportData(bpy.types.Operator):
# 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')
try:
f = open(os.path.join(getPresetpaths()[0], self.filename), 'r')
except (FileNotFoundError, IOError):
f = open(os.path.join(getPresetpaths()[1], self.filename), 'r')
settings = f.readline()
f.close()
#print(settings)
settings = eval(settings)
settings = ast.literal_eval(settings)
#use old attractup
if type(settings['attractUp']) == float:
atr = settings['attractUp']
settings['attractUp'] = [0, 0, atr, atr]
#use old leaf rotations
if 'leafDownAngle' not in settings:
l = settings['levels']
settings['leafDownAngle'] = settings['downAngle'][min(l, 3)]
settings['leafDownAngleV'] = settings['downAngleV'][min(l, 3)]
settings['leafRotate'] = settings['rotate'][min(l, 3)]
settings['leafRotateV'] = settings['rotateV'][min(l, 3)]
#zero leaf bend
settings['bend'] = 0
# 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"""
"""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']
presets = [a for a in os.listdir(getPresetpaths()[0]) if a[-3:] == '.py']
presets.extend([a for a in os.listdir(getPresetpaths()[1]) 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"
bl_label = "Sapling: Add Tree"
bl_options = {'REGISTER', 'UNDO'}
def objectList(self, context):
objects = []
bObjects = bpy.data.objects
# try:
# bObjects = bpy.data.objects
# except AttributeError:
# pass
# else:
for obj in bObjects:
if (obj.type in ['MESH', 'CURVE', 'SURFACE']) and (obj.name not in ['tree', 'leaves']):
objects.append((obj.name, obj.name, ""))
return objects
def update_tree(self, context):
self.do_update = True
def update_leaves(self, context):
if self.showLeaves:
self.do_update = True
else:
self.do_update = False
def no_update_tree(self, context):
self.do_update = False
@ -189,20 +291,27 @@ class AddTree(bpy.types.Operator):
max=1,
default=0, update=update_tree)
levels = IntProperty(name='Levels',
description='Number of recursive branches (Levels, note that last level is also used for generating leaves)',
description='Number of recursive branches (Levels)',
min=1,
max=6,
soft_max=4,
default=3, update=update_tree)
length = FloatVectorProperty(name='Length',
description='The relative lengths of each branch level (nLength)',
min=1e-6,
min=0.000001,
default=[1, 0.3, 0.6, 0.45],
size=4, update=update_tree)
lengthV = FloatVectorProperty(name='Length Variation',
description='The relative length variations of each level (nLengthV)',
min=0.0,
max=1.0,
default=[0, 0, 0, 0],
size=4, update=update_tree)
taperCrown = FloatProperty(name='Taper Crown',
description='Shorten trunk splits toward outside of tree',
min=0.0,
soft_max=1.0,
default=0, update=update_tree)
branches = IntVectorProperty(name='Branches',
description='The number of branches grown at each level (nBranches)',
min=0,
@ -232,8 +341,16 @@ class AddTree(bpy.types.Operator):
segSplits = FloatVectorProperty(name='Segment Splits',
description='Number of splits per segment (nSegSplits)',
min=0,
soft_max=3,
default=[0, 0, 0, 0],
size=4, update=update_tree)
splitByLen = BoolProperty(name='Split relative to length',
description='Split proportional to branch length',
default=False, update=update_tree)
rMode = EnumProperty(name="", #"Branching Mode"
description='Branching and Rotation Mode',
items=branchmodes,
default="rotate", update=update_tree)
splitAngle = FloatVectorProperty(name='Split Angle',
description='Angle of branch splitting (nSplitAngle)',
default=[0, 0, 0, 0],
@ -244,33 +361,94 @@ class AddTree(bpy.types.Operator):
size=4, update=update_tree)
scale = FloatProperty(name='Scale',
description='The tree scale (Scale)',
min=0.001,
min=0.0,
default=13.0, update=update_tree)
scaleV = FloatProperty(name='Scale Variation',
description='The variation in the tree scale (ScaleV)',
default=3.0, update=update_tree)
attractUp = FloatProperty(name='Vertical Attraction',
attractUp = FloatVectorProperty(name='Vertical Attraction',
description='Branch upward attraction',
default=0.0, update=update_tree)
default=[0, 0, 0, 0],
size=4, update=update_tree)
attractOut = FloatVectorProperty(name='Outward Attraction',
description='Branch outward attraction',
default=[0, 0, 0, 0],
min=0.0,
max=1.0,
size=4, update=update_tree)
shape = EnumProperty(name='Shape',
description='The overall shape of the tree (Shape) - WARNING: at least three "Levels" of branching are needed',
items=shapeList,
description='The overall shape of the tree (Shape)',
items=shapeList3,
default='7', update=update_tree)
baseSize = FloatProperty(name='Base Size',
description='Fraction of tree height with no branches (BaseSize)',
min=0.001,
shapeS = EnumProperty(name='Secondary Branches Shape',
description='The shape of secondary splits',
items=shapeList4,
default='4', update=update_tree)
customShape = FloatVectorProperty(name='Custom Shape',
description='custom shape branch length at (Base, Middle, Middle Position, Top)',
size=4,
min=.01,
max=1,
default=[.5, 1.0, .3, .5], update=update_tree)
branchDist = FloatProperty(name='Branch Distribution',
description='Adjust branch spacing to put more branches at the top or bottom of the tree',
min=0.1,
soft_max=10,
default=1.0, update=update_tree)
nrings = IntProperty(name='Branch Rings',
description='grow branches in rings',
min=0,
default=0, update=update_tree)
baseSize = FloatProperty(name='Trunk Height',
description='Fraction of tree height with no branches (Base Size)',
min=0.0,
max=1.0,
default=0.4, update=update_tree)
baseSize_s = FloatProperty(name='Secondary Base Size',
description='Factor to decrease base size for each level',
min=0.0,
max=1.0,
default=0.25, update=update_tree)
splitHeight = FloatProperty(name='Split Height',
description='Fraction of tree height with no splits',
min=0.0,
max=1.0,
default=0.2, update=update_tree)
splitBias = FloatProperty(name='splitBias',
description='Put more splits at the top or bottom of the tree',
soft_min=-2.0,
soft_max=2.0,
default=0.0, update=update_tree)
ratio = FloatProperty(name='Ratio',
description='Base radius size (Ratio)',
min=0.0,
default=0.015, update=update_tree)
minRadius = FloatProperty(name='Minimum Radius',
description='Minimum branch Radius',
min=0.0,
default=0.0, update=update_tree)
closeTip = BoolProperty(name='Close Tip',
description='Set radius at branch tips to zero',
default=False, update=update_tree)
rootFlare = FloatProperty(name='Root Flare',
description='Root radius factor',
min=1.0,
default=1.0, update=update_tree)
autoTaper = BoolProperty(name='Auto Taper',
description='Calculate taper automaticly based on branch lengths',
default=True, update=update_tree)
taper = FloatVectorProperty(name='Taper',
description='The fraction of tapering on each branch (nTaper)',
min=0.0,
max=1.0,
default=[1, 1, 1, 1],
size=4, update=update_tree)
radiusTweak = FloatVectorProperty(name='Tweak Radius',
description='multiply radius by this factor',
min=0.0,
max=1.0,
default=[1, 1, 1, 1],
size=4, update=update_tree)
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)'),
@ -282,13 +460,17 @@ class AddTree(bpy.types.Operator):
default=[90, 60, 45, 45],
size=4, update=update_tree)
downAngleV = FloatVectorProperty(name='Down Angle Variation',
description='Variation in the down angle (nDownAngleV)',
description='Angle to decrease Down Angle by towards end of parent branch (negative values add random variation)',
default=[0, -50, 10, 10],
size=4, update=update_tree)
useOldDownAngle = BoolProperty(name='Use old down angle variation',
default=False, update=update_tree)
useParentAngle = BoolProperty(name = 'Use parent angle',
description = '(first level) Rotate branch to match parent branch',
default=True, update=update_tree)
rotate = FloatVectorProperty(name='Rotate Angle',
description=('The angle of a new branch around the one it grew from '
'(nRotate)'),
default=[140, 140, 140, 77],
description='The angle of a new branch around the one it grew from (negative values rotate opposite from the previous)',
default=[137.5, 137.5, 137.5, 137.5],
size=4, update=update_tree)
rotateV = FloatVectorProperty(name='Rotate Angle Variation',
description='Variation in the rotate angle (nRotateV)',
@ -300,11 +482,18 @@ class AddTree(bpy.types.Operator):
default=1.0, update=update_tree)
scaleV0 = FloatProperty(name='Radius Scale Variation',
description='Variation in the radius scale (0ScaleV)',
min=0.0,
max=1.0,
default=0.2, update=update_tree)
pruneWidth = FloatProperty(name='Prune Width',
description='The width of the envelope (PruneWidth)',
min=0.0,
default=0.4, update=update_tree)
pruneBase = FloatProperty(name='Prune Base Height',
description='The height of the base of the envelope, bound by trunk height',
min=0.0,
max=1.0,
default=0.3, update=update_tree)
pruneWidthPeak = FloatProperty(name='Prune Width Peak',
description=('Fraction of envelope height where the maximum width '
'occurs (PruneWidthPeak)'),
@ -323,36 +512,71 @@ class AddTree(bpy.types.Operator):
min=0.0,
max=1.0,
default=1.0, update=update_tree)
leaves = FloatProperty(name='Leaves',
description='Maximum number of leaves per branch (Leaves)',
min=0,
max=50,
leaves = IntProperty(name='Leaves',
description='Maximum number of leaves per branch (negative values grow leaves from branch tip (palmate compound leaves))',
default=25, update=update_tree)
leafDownAngle = FloatProperty(name='Leaf Down Angle',
description='The angle between a new leaf and the branch it grew from',
default=45, update=update_leaves)
leafDownAngleV = FloatProperty(name='Leaf Down Angle Variation',
description='Angle to decrease Down Angle by towards end of parent branch (negative values add random variation)',
default=10, update=update_tree)
leafRotate = FloatProperty(name='Leaf Rotate Angle',
description='The angle of a new leaf around the one it grew from (negative values rotate opposite from previous)',
default=137.5, update=update_tree)
leafRotateV = FloatProperty(name='Leaf Rotate Angle Variation',
description='Variation in the rotate angle',
default=0.0, update=update_leaves)
leafScale = FloatProperty(name='Leaf Scale',
description='The scaling applied to the whole leaf (LeafScale)',
min=0.0,
default=0.17, update=update_tree)
default=0.17, update=update_leaves)
leafScaleX = FloatProperty(name='Leaf Scale X',
description=('The scaling applied to the x direction of the leaf '
'(LeafScaleX)'),
min=0.0,
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')),
default='hex', update=update_tree)
bend = FloatProperty(name='Leaf Bend',
description='The proportion of bending applied to the leaf (Bend)',
min=0.0,
max=1.0,
default=0.0, update=update_tree)
default=1.0, update=update_leaves)
leafScaleT = FloatProperty(name='Leaf Scale Taper',
description='scale leaves toward the tip or base of the patent branch',
min = -1.0,
max = 1.0,
default=0.0, update=update_leaves)
leafScaleV = FloatProperty(name='Leaf Scale Variation',
description='randomize leaf scale',
min = 0.0,
max = 1.0,
default=0.0, update=update_leaves)
leafShape = EnumProperty(name='Leaf Shape',
description='The shape of the leaves',
items=(('hex', 'Hexagonal', '0'), ('rect', 'Rectangular', '1'), ('dFace', 'DupliFaces', '2'), ('dVert', 'DupliVerts', '3')),
default='hex', update=update_leaves)
leafDupliObj = EnumProperty(name='Leaf Object',
description='Object to use for leaf instancing if Leaf Shape is DupliFaces or DupliVerts',
items=objectList,
update=update_leaves)
# bend = FloatProperty(name='Leaf Bend',
# description='The proportion of bending applied to the leaf (Bend)',
# min=0.0,
# max=1.0,
# default=0.0, update=update_leaves)
leafangle = FloatProperty(name='Leaf Angle',
description='Leaf vertical attraction',
default=0.0, update=update_leaves)
horzLeaves = BoolProperty(name='Horizontal leaves',
description='Leaves face upwards',
default=True, update=update_leaves)
leafDist = EnumProperty(name='Leaf Distribution',
description='The way leaves are distributed on branches',
items=shapeList,
default='4', update=update_tree)
items=shapeList4,
default='6', update=update_tree)
bevelRes = IntProperty(name='Bevel Resolution',
description='The bevel resolution of the curves',
min=0,
max=32,
default=0, update=update_tree)
resU = IntProperty(name='Curve Resolution',
description='The resolution along the curves',
@ -361,21 +585,68 @@ class AddTree(bpy.types.Operator):
handleType = EnumProperty(name='Handle Type',
description='The type of handles used in the spline',
items=handleList,
default='1', update=update_tree)
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,
default=1, update=update_tree)
windSpeed = FloatProperty(name='Wind Speed',
description='The wind speed to apply to the armature (WindSpeed)',
default=2.0, update=update_tree)
windGust = FloatProperty(name='Wind Gust',
description='The greatest increase over Wind Speed (WindGust)',
default=0.0, update=update_tree)
default='0', update=update_tree)
armAnim = BoolProperty(name='Armature Animation',
description='Whether animation is added to the armature',
default=False, update=update_tree)
previewArm = BoolProperty(name='Fast Preview',
description='Disable armature modifier, hide tree, and set bone display to wire, for fast playback',
##Disable skin modifier and hide tree and armature, for fast playback
default=False, update=update_tree)
leafAnim = BoolProperty(name='Leaf Animation',
description='Whether animation is added to the leaves',
default=False, update=update_tree)
frameRate = FloatProperty(name='Animation Speed',
description=('Adjust speed of animation, relative to scene frame rate'),
min=0.001,
default=1, update=update_tree)
loopFrames = IntProperty(name='Loop Frames',
description='Number of frames to make the animation loop for, zero is disabled',
min=0,
default=0, update=update_tree)
# windSpeed = FloatProperty(name='Wind Speed',
# description='The wind speed to apply to the armature',
# default=2.0, update=update_tree)
# windGust = FloatProperty(name='Wind Gust',
# description='The greatest increase over Wind Speed',
# default=0.0, update=update_tree)
wind= FloatProperty(name='Overall Wind Strength',
description='The intensity of the wind to apply to the armature',
default=1.0, update=update_tree)
gust = FloatProperty(name='Wind Gust Strength',
description='The amount of directional movement, (from the positive Y direction)',
default=1.0, update=update_tree)
gustF = FloatProperty(name='Wind Gust Fequency',
description='The Fequency of directional movement',
default=0.075, update=update_tree)
af1 = FloatProperty(name='Amplitude',
description='Multiplier for noise amplitude',
default=1.0, update=update_tree)
af2 = FloatProperty(name='Frequency',
description='Multiplier for noise fequency',
default=1.0, update=update_tree)
af3 = FloatProperty(name='Randomness',
description='Random offset in noise',
default=4.0, update=update_tree)
makeMesh = BoolProperty(name='Make Mesh',
description='Convert curves to mesh, uses skin modifier, enables armature simplification',
default=False, update=update_tree)
armLevels = IntProperty(name='Armature Levels',
description='Number of branching levels to make bones for, 0 is all levels',
min=0,
default=2, update=update_tree)
boneStep = IntVectorProperty(name='Bone Length',
description='Number of stem segments per bone',
min=1,
default=[1, 1, 1, 1],
size=4, update=update_tree)
presetName = StringProperty(name='Preset Name',
description='The name of the preset to be saved',
@ -384,22 +655,21 @@ class AddTree(bpy.types.Operator):
limitImport = BoolProperty(name='Limit Import',
description='Limited imported tree to 2 levels & no leaves for speed',
default=True, update=no_update_tree)
overwrite = BoolProperty(name='Overwrite',
description='When checked, overwrite existing preset files when saving',
default=False, update=no_update_tree)
startCurv = FloatProperty(name='Trunk Starting Angle',
description=('The angle between vertical and the starting direction '
'of the trunk'),
min=0.0,
max=360,
default=0.0, update=update_tree)
# startCurv = FloatProperty(name='Trunk Starting Angle',
# description=('The angle between vertical and the starting direction '
# 'of the trunk'),
# min=0.0,
# max=360,
# default=0.0, update=update_tree)
@classmethod
def poll(cls, context):
return context.mode == 'OBJECT'
def check(self, context):
# TODO, should check exact vars which require redraw
return True
def draw(self, context):
layout = self.layout
@ -419,25 +689,27 @@ class AddTree(bpy.types.Operator):
row.prop(self, 'resU')
box.prop(self, 'handleType')
sub = box.row()
sub.active = self.levels >= 3
sub.prop(self, 'shape')
box.prop(self, 'seed')
box.prop(self, 'ratio')
box.prop(self, 'shape')
col = box.column()
col.prop(self, 'customShape')
row = box.row()
box.prop(self, 'shapeS')
box.prop(self, 'branchDist')
box.prop(self, 'nrings')
box.prop(self, 'seed')
box.label("Tree Scale:")
row = box.row()
row.prop(self, 'scale')
row.prop(self, 'scaleV')
row = box.row()
row.prop(self, 'scale0')
row.prop(self, 'scaleV0')
# 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 = []
for a, b in (self.as_keywords(ignore=("chooseSet", "presetName", "limitImport", "do_update"))).items():
for a, b in (self.as_keywords(ignore=("chooseSet", "presetName", "limitImport", "do_update", "overwrite", "leafDupliObj"))).items():
# If the property is a vector property then add the slice to the list
try:
len(b)
@ -451,94 +723,173 @@ class AddTree(bpy.types.Operator):
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.operator('sapling.exportdata').data = repr([repr(data), self.presetName, self.overwrite])
row = box.row()
row.label(" ")
row.prop(self, 'overwrite')
row = box.row()
row.menu('sapling.presetmenu', text='Load Preset')
row.prop(self, 'limitImport')
elif self.chooseSet == '1':
box = layout.box()
box.label("Branch Radius:")
row = box.row()
row.prop(self, 'bevel')
row.prop(self, 'bevelRes')
box.prop(self, 'ratio')
row = box.row()
row.prop(self, 'scale0')
row.prop(self, 'scaleV0')
box.prop(self, 'ratioPower')
box.prop(self, 'minRadius')
box.prop(self, 'closeTip')
box.prop(self, 'rootFlare')
box.prop(self, 'autoTaper')
split = box.split()
col = split.column()
col.prop(self, 'taper')
col = split.column()
col.prop(self, 'radiusTweak')
elif self.chooseSet == '2':
box = layout.box()
box.label("Branch Splitting:")
box.prop(self, 'levels')
box.prop(self, 'baseSplits')
box.prop(self, 'baseSize')
row = box.row()
row.prop(self, 'baseSize')
row.prop(self, 'baseSize_s')
box.prop(self, 'splitHeight')
box.prop(self, 'splitBias')
box.prop(self, 'splitByLen')
split = box.split()
col = split.column()
col.prop(self, 'branches')
col.prop(self, 'splitAngle')
col.prop(self, 'downAngle')
col.prop(self, 'rotate')
col.prop(self, 'attractOut')
col = split.column()
col.prop(self, 'segSplits')
col.prop(self, 'splitAngleV')
col.prop(self, 'downAngleV')
col.prop(self, 'rotateV')
box.prop(self, 'ratioPower')
elif self.chooseSet == '2':
box = layout.box()
box.label("Branch Growth:")
box.prop(self, 'startCurv')
box.prop(self, 'attractUp')
split = box.split()
col = split.column()
col.prop(self, 'length')
col.prop(self, 'curve')
col.prop(self, 'curveBack')
col = split.column()
col.prop(self, 'lengthV')
col.prop(self, 'curveV')
col.prop(self, 'taper')
col.label("Branching Mode:")
col.prop(self, 'rMode')
box.column().prop(self, 'curveRes')
elif self.chooseSet == '3':
box = layout.box()
box.label("Pruning:")
box.label("Branch Growth:")
box.prop(self, 'taperCrown')
split = box.split()
col = split.column()
col.prop(self, 'length')
col.prop(self, 'downAngle')
col.prop(self, 'curve')
col.prop(self, 'curveBack')
col = split.column()
col.prop(self, 'lengthV')
col.prop(self, 'downAngleV')
col.prop(self, 'curveV')
col.prop(self, 'attractUp')
box.prop(self, 'useOldDownAngle')
box.prop(self, 'useParentAngle')
elif self.chooseSet == '4':
box = layout.box()
box.label("Prune:")
box.prop(self, 'prune')
box.prop(self, 'pruneRatio')
box.prop(self, 'pruneWidth')
row = box.row()
row.prop(self, 'pruneWidth')
row.prop(self, 'pruneBase')
box.prop(self, 'pruneWidthPeak')
row = box.row()
row.prop(self, 'prunePowerHigh')
row.prop(self, 'prunePowerLow')
elif self.chooseSet == '4':
elif self.chooseSet == '5':
box = layout.box()
box.label("Leaves:")
box.prop(self, 'showLeaves')
box.prop(self, 'leafShape')
box.prop(self, 'leafDupliObj')
box.prop(self, 'leaves')
box.prop(self, 'leafDist')
box.label("")
row = box.row()
row.prop(self, 'leafDownAngle')
row.prop(self, 'leafDownAngleV')
row = box.row()
row.prop(self, 'leafRotate')
row.prop(self, 'leafRotateV')
box.label("")
row = box.row()
row.prop(self, 'leafScale')
row.prop(self, 'leafScaleX')
box.prop(self, 'bend')
row = box.row()
row.prop(self, 'leafScaleT')
row.prop(self, 'leafScaleV')
elif self.chooseSet == '5':
box.prop(self, 'horzLeaves')
box.prop(self, 'leafangle')
#box.label(" ")
#box.prop(self, 'bend')
elif self.chooseSet == '6':
box = layout.box()
box.label("Armature and Animation:")
box.label("Armature:")
row = box.row()
row.prop(self, 'useArm')
row.prop(self, 'armAnim')
row = box.row()
row.prop(self, 'windSpeed')
row.prop(self, 'windGust')
box.prop(self, 'makeMesh')
box.label("Armature Simplification:")
box.prop(self, 'armLevels')
box.prop(self, 'boneStep')
elif self.chooseSet == '7':
box = layout.box()
box.label("Finalize All Other Settings First!")
box.prop(self, 'armAnim')
box.prop(self, 'leafAnim')
box.prop(self, 'previewArm')
box.prop(self, 'frameRate')
box.prop(self, 'loopFrames')
#row = box.row()
#row.prop(self, 'windSpeed')
#row.prop(self, 'windGust')
box.label('Wind Settings:')
box.prop(self, 'wind')
row = box.row()
row.prop(self, 'gust')
row.prop(self, 'gustF')
box.label('Leaf Wind Settings:')
box.prop(self, 'af1')
box.prop(self, 'af2')
box.prop(self, 'af3')
def execute(self, context):
# Ensure the use of the global variables
@ -550,12 +901,13 @@ class AddTree(bpy.types.Operator):
for a, b in settings.items():
setattr(self, a, b)
if self.limitImport:
setattr(self, 'levels', 2)
setattr(self, 'levels', min(settings['levels'], 2))
setattr(self, 'showLeaves', False)
useSet = False
if not self.do_update:
return {'PASS_THROUGH'}
addTree(self)
#cProfile.runctx("addTree(self)", globals(), locals())
print("Tree creation in %0.1fs" %(time.time()-start_time))
return {'FINISHED'}
@ -565,17 +917,14 @@ class AddTree(bpy.types.Operator):
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')
self.layout.operator(AddTree.bl_idname, text="Sapling Tree Gen", icon='CURVE_DATA')
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_curve_add.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)

View File

@ -0,0 +1 @@
{'handleType': '0', 'rotate': (99.5, 137.5, 137.5, 137.5), 'baseSize_s': 0.1600000560283661, 'af2': 1.0, 'pruneRatio': 0.75, 'radiusTweak': (1.0, 1.0, 1.0, 1.0), 'pruneWidthPeak': 0.5, 'boneStep': (1, 1, 1, 1), 'nrings': 0, 'leafScale': 0.4000000059604645, 'makeMesh': False, 'baseSize': 0.30000001192092896, 'lengthV': (0.0, 0.10000000149011612, 0.0, 0.0), 'shapeS': '10', 'pruneBase': 0.11999999731779099, 'af3': 4.0, 'loopFrames': 0, 'horzLeaves': True, 'curveRes': (8, 5, 3, 1), 'minRadius': 0.001500000013038516, 'leafDist': '6', 'rotateV': (15.0, 0.0, 0.0, 0.0), 'bevel': True, 'curveBack': (0.0, 0.0, 0.0, 0.0), 'leafScaleV': 0.15000000596046448, 'prunePowerHigh': 0.5, 'rootFlare': 1.0, 'prune': False, 'branches': (0, 55, 10, 1), 'taperCrown': 0.5, 'useArm': False, 'splitBias': 0.5499999523162842, 'segSplits': (0.10000000149011612, 0.5, 0.20000000298023224, 0.0), 'resU': 4, 'useParentAngle': True, 'ratio': 0.014999999664723873, 'taper': (1.0, 1.0, 1.0, 1.0), 'length': (0.800000011920929, 0.6000000238418579, 0.5, 0.10000000149011612), 'scale0': 1.0, 'scaleV': 2.0, 'leafRotate': 137.5, 'shape': '7', 'scaleV0': 0.10000000149011612, 'leaves': 150, 'scale': 5.0, 'leafShape': 'hex', 'prunePowerLow': 0.0010000000474974513, 'splitAngle': (18.0, 18.0, 22.0, 0.0), 'seed': 0, 'showLeaves': True, 'downAngle': (0.0, 26.209999084472656, 52.55999755859375, 30.0), 'leafDownAngle': 30.0, 'autoTaper': True, 'rMode': 'rotate', 'leafScaleX': 0.20000000298023224, 'leafScaleT': 0.10000000149011612, 'gust': 1.0, 'armAnim': False, 'wind': 1.0, 'leafRotateV': 15.0, 'baseSplits': 3, 'attractOut': (0.0, 0.800000011920929, 0.0, 0.0), 'armLevels': 2, 'leafAnim': False, 'ratioPower': 1.2000000476837158, 'splitHeight': 0.20000000298023224, 'splitByLen': True, 'af1': 1.0, 'branchDist': 1.5, 'closeTip': False, 'previewArm': False, 'attractUp': (3.5, -1.899843692779541, 0.0, 0.0), 'bevelRes': 1, 'pruneWidth': 0.3400000035762787, 'gustF': 0.07500000298023224, 'leafangle': -12.0, 'curveV': (20.0, 50.0, 75.0, 0.0), 'useOldDownAngle': True, 'leafDownAngleV': -10.0, 'frameRate': 1.0, 'splitAngleV': (5.0, 5.0, 5.0, 0.0), 'levels': 2, 'downAngleV': (0.0, 10.0, 10.0, 10.0), 'customShape': (0.5, 1.0, 0.30000001192092896, 0.5), 'curve': (0.0, -15.0, 0.0, 0.0)}

View File

@ -0,0 +1 @@
{'pruneRatio': 1.0, 'wind': 1.0, 'prune': False, 'splitByLen': True, 'attractUp': (0.0, 0.3499999940395355, 0.25, 0.15000000596046448), 'segSplits': (0.0, 0.3499999940395355, 0.6000000238418579, 0.0), 'rMode': 'rotate', 'rotate': (99.5, 137.5, -45.0, -60.0), 'curve': (0.0, 20.0, -10.0, 0.0), 'af2': 1.0, 'seed': 0, 'length': (1.0, 0.20000000298023224, 0.550000011920929, 0.44999998807907104), 'attractOut': (0.0, 0.0, 0.0, 0.0), 'leafScaleT': 0.0, 'scaleV': 15.0, 'splitHeight': 0.20000000298023224, 'minRadius': 0.0020000000949949026, 'leafRotate': 137.5, 'curveRes': (12, 4, 3, 2), 'curveV': (40.0, 30.0, 15.0, 10.0), 'nrings': 0, 'levels': 4, 'frameRate': 1.0, 'ratioPower': 1.2000000476837158, 'leafDownAngle': 45.0, 'armLevels': 2, 'branches': (0, 75, 16, 10), 'splitAngleV': (0.0, 0.0, 0.0, 0.0), 'shape': '8', 'rotateV': (15.0, 0.0, 15.0, 45.0), 'loopFrames': 0, 'curveBack': (0.0, 0.0, 0.0, 0.0), 'taperCrown': 0.0, 'prunePowerLow': 0.0010000000474974513, 'handleType': '0', 'af3': 4.0, 'useParentAngle': True, 'customShape': (0.5, 1.0, 0.3499999940395355, 0.10000000149011612), 'scale0': 1.0, 'rootFlare': 1.2999999523162842, 'leafScaleV': 0.0, 'leafScale': 0.17000000178813934, 'leafangle': 0.0, 'scaleV0': 0.10000000149011612, 'downAngleV': (0.0, 30.0, 10.0, 10.0), 'af1': 1.0, 'autoTaper': True, 'scale': 35.0, 'gustF': 0.07500000298023224, 'ratio': 0.014999999664723873, 'leafScaleX': 1.0, 'shapeS': '7', 'bevelRes': 1, 'bevel': True, 'leaves': 25, 'splitAngle': (0.0, 12.0, 18.0, 0.0), 'downAngle': (90.0, 130.0, 45.0, 45.0), 'previewArm': False, 'radiusTweak': (1.0, 1.0, 1.0, 1.0), 'showLeaves': False, 'leafAnim': False, 'baseSize': 0.33000001311302185, 'gust': 1.0, 'horzLeaves': True, 'baseSize_s': 0.5, 'leafDownAngleV': 10.0, 'makeMesh': False, 'leafDist': '6', 'armAnim': False, 'baseSplits': 0, 'lengthV': (0.0, 0.10000000149011612, 0.25, 0.25), 'branchDist': 1.850000023841858, 'useArm': False, 'useOldDownAngle': False, 'taper': (1.0, 1.0, 1.0, 1.0), 'pruneBase': 0.30000001192092896, 'splitBias': 0.0, 'boneStep': (1, 1, 1, 1), 'leafShape': 'hex', 'resU': 4, 'prunePowerHigh': 0.5, 'closeTip': True, 'pruneWidth': 0.4000000059604645, 'leafRotateV': 0.0, 'pruneWidthPeak': 0.6000000238418579}

View File

@ -0,0 +1 @@
{'leafScaleT': -0.5, 'shapeS': '10', 'scaleV': 2.0, 'resU': 4, 'boneStep': (1, 1, 1, 1), 'af3': 4.0, 'baseSize': 0.4000000059604645, 'prunePowerLow': 0.0010000000474974513, 'leafRotateV': 0.0, 'rootFlare': 1.0, 'customShape': (0.699999988079071, 1.0, 0.20000000298023224, 0.800000011920929), 'attractOut': (0.0, 0.75, 0.25, 0.0), 'useArm': False, 'branches': (0, 50, 10, 16), 'leafDownAngle': 45.0, 'length': (1.0, 0.30000001192092896, 0.5, 0.20000000298023224), 'segSplits': (0.25, 0.4000000059604645, 0.5, 0.0), 'makeMesh': False, 'curveV': (400.0, 150.0, 100.0, 0.0), 'curveBack': (0.0, 0.0, 0.0, 0.0), 'af1': 1.0, 'closeTip': False, 'frameRate': 1.0, 'leafangle': -10.0, 'af2': 1.0, 'rMode': 'rotate', 'leafScaleV': 0.0, 'rotateV': (15.0, 0.0, 0.0, 0.0), 'useParentAngle': False, 'taperCrown': 0.0, 'minRadius': 0.001500000013038516, 'splitAngleV': (5.0, 5.0, 0.0, 0.0), 'scaleV0': 0.10000000149011612, 'bevel': True, 'leafDownAngleV': 10.0, 'previewArm': False, 'showLeaves': True, 'ratioPower': 1.25, 'handleType': '0', 'branchDist': 1.0, 'leafScaleX': 0.20000000298023224, 'prune': False, 'splitHeight': 0.30000001192092896, 'baseSplits': 2, 'baseSize_s': 0.25, 'downAngle': (90.0, 90.0, 30.0, 30.0), 'bevelRes': 1, 'leafAnim': False, 'loopFrames': 0, 'lengthV': (0.0, 0.0, 0.0, 0.0), 'gust': 1.0, 'downAngleV': (0.0, 90.0, 15.0, 10.0), 'leafRotate': 137.5, 'wind': 1.0, 'leaves': -5, 'curve': (0.0, -20.0, -20.0, 0.0), 'radiusTweak': (1.0, 1.0, 1.0, 1.0), 'pruneRatio': 1.0, 'pruneBase': 0.30000001192092896, 'armAnim': False, 'splitBias': 0.0, 'rotate': (99.5, 137.5, 137.5, 137.5), 'armLevels': 2, 'scale': 6.0, 'prunePowerHigh': 0.5, 'nrings': 0, 'splitByLen': True, 'leafShape': 'hex', 'splitAngle': (15.0, 20.0, 25.0, 0.0), 'ratio': 0.019999999552965164, 'scale0': 1.0, 'autoTaper': True, 'pruneWidth': 0.4000000059604645, 'leafScale': 0.17000000178813934, 'seed': 0, 'curveRes': (16, 5, 3, 1), 'horzLeaves': True, 'useOldDownAngle': False, 'levels': 4, 'pruneWidthPeak': 0.6000000238418579, 'attractUp': (0.0, -0.3499999940395355, -0.20000000298023224, 0.0), 'taper': (1.0, 1.0, 1.0, 1.0), 'leafDist': '6', 'gustF': 0.07500000298023224, 'shape': '8'}

View File

@ -0,0 +1 @@
{'leafDownAngle': 45.0, 'handleType': '0', 'radiusTweak': (1.0, 1.0, 1.0, 1.0), 'useArm': False, 'rootFlare': 1.0, 'segSplits': (0.44999998807907104, 0.5, 0.800000011920929, 0.0), 'leafRotateV': 0.0, 'leaves': 32, 'baseSplits': 1, 'rotate': (99.5, 137.5, 137.5, 137.5), 'scale': 8.0, 'makeMesh': False, 'leafDownAngleV': 10.0, 'curve': (0.0, 30.0, 0.0, 0.0), 'splitBias': 0.0, 'leafScale': 0.18000000715255737, 'levels': 3, 'leafScaleT': 0.3499999940395355, 'seed': 0, 'autoTaper': True, 'pruneWidthPeak': 0.6000000238418579, 'branchDist': 1.25, 'prune': False, 'splitAngle': (8.0, 18.0, 18.0, 0.0), 'shapeS': '7', 'useParentAngle': True, 'af1': 1.0, 'armAnim': False, 'resU': 4, 'ratioPower': 1.2000000476837158, 'scaleV': 2.0, 'splitHeight': 0.20000000298023224, 'leafRotate': 137.5, 'customShape': (0.5, 1.0, 0.30000001192092896, 0.5), 'shape': '7', 'ratio': 0.019999999552965164, 'rMode': 'rotate', 'downAngle': (90.0, 48.0, 45.0, 45.0), 'bevelRes': 2, 'showLeaves': True, 'wind': 1.0, 'loopFrames': 0, 'splitByLen': True, 'lengthV': (0.0, 0.029999999329447746, 0.15000000596046448, 0.0), 'leafShape': 'hex', 'downAngleV': (0.0, 48.0, 10.0, 10.0), 'leafangle': -35.0, 'bevel': True, 'gustF': 0.07500000298023224, 'taper': (1.0, 1.0, 1.0, 1.0), 'previewArm': False, 'frameRate': 1.0, 'curveBack': (0.0, -30.0, -20.0, 0.0), 'taperCrown': 0.20000000298023224, 'rotateV': (15.0, 0.0, 0.0, 0.0), 'scaleV0': 0.20000000298023224, 'gust': 1.0, 'horzLeaves': True, 'attractUp': (-0.5, -0.699999988079071, 0.0, 0.0), 'splitAngleV': (2.0, 5.0, 5.0, 0.0), 'pruneRatio': 1.0, 'curveV': (10.0, 35.0, 35.0, 0.0), 'prunePowerHigh': 0.5, 'closeTip': False, 'leafScaleV': 0.20000000298023224, 'leafAnim': False, 'minRadius': 0.0020000000949949026, 'af3': 4.0, 'attractOut': (0.0, 0.4000000059604645, 0.5, 0.0), 'branches': (0, 110, 18, 10), 'leafScaleX': 0.6499999761581421, 'length': (1.0, 0.46000000834465027, 0.44999998807907104, 0.44999998807907104), 'useOldDownAngle': False, 'armLevels': 2, 'boneStep': (1, 1, 1, 1), 'pruneBase': 0.30000001192092896, 'curveRes': (8, 5, 3, 1), 'prunePowerLow': 0.0010000000474974513, 'af2': 1.0, 'pruneWidth': 0.4000000059604645, 'nrings': 0, 'baseSize_s': 0.25, 'baseSize': 0.2800000011920929, 'leafDist': '6', 'scale0': 1.0}

View File

@ -0,0 +1 @@
{'downAngleV': (0.0, 42.0, 10.0, 10.0), 'useOldDownAngle': False, 'splitBias': 0.0, 'branchDist': 1.600000023841858, 'downAngle': (90.0, 110.0, 45.0, 45.0), 'leafScale': 0.20000000298023224, 'baseSize': 0.06799984723329544, 'shapeS': '4', 'leafScaleX': 0.019999999552965164, 'nrings': 7, 'gustF': 0.07500000298023224, 'showLeaves': True, 'taperCrown': 0.0, 'curveBack': (0.0, 0.0, 0.0, 0.0), 'leafShape': 'rect', 'makeMesh': False, 'scale0': 1.0, 'length': (1.0, 0.3199999928474426, 0.75, 0.44999998807907104), 'ratioPower': 1.0, 'taper': (1.0, 1.0, 1.0, 1.0), 'baseSize_s': 0.25, 'splitHeight': 0.20000000298023224, 'handleType': '0', 'pruneBase': 0.30000001192092896, 'attractUp': (2.0, 0.0, 0.5, 0.5), 'boneStep': (1, 1, 1, 1), 'seed': 0, 'leafDownAngle': 65.0, 'attractOut': (0.0, 0.0, 0.0, 0.0), 'leafAnim': False, 'gust': 1.0, 'curveV': (100.0, 100.0, 100.0, 0.0), 'splitAngle': (0.0, 22.0, 25.0, 0.0), 'prunePowerLow': 0.0010000000474974513, 'leafangle': -10.0, 'frameRate': 1.0, 'pruneRatio': 1.0, 'rMode': 'rotate', 'shape': '8', 'segSplits': (0.0, 0.30000001192092896, 0.4000000059604645, 0.0), 'branches': (0, 36, 7, 10), 'prunePowerHigh': 0.5, 'af1': 1.0, 'closeTip': False, 'splitAngleV': (0.0, 5.0, 0.0, 0.0), 'ratio': 0.019999999552965164, 'minRadius': 0.001500000013038516, 'levels': 3, 'leafRotate': 137.5, 'armLevels': 2, 'horzLeaves': False, 'pruneWidth': 0.4000000059604645, 'baseSplits': 0, 'scale': 4.0, 'leafScaleV': 0.10000000149011612, 'splitByLen': True, 'useParentAngle': True, 'previewArm': False, 'wind': 1.0, 'leafDist': '3', 'leafScaleT': 0.25, 'bevel': True, 'resU': 4, 'leafDownAngleV': 55.0, 'pruneWidthPeak': 0.6000000238418579, 'af3': 4.0, 'scaleV': 1.0, 'rootFlare': 1.0, 'loopFrames': 0, 'curve': (0.0, -40.0, -30.0, 0.0), 'leaves': 500, 'scaleV0': 0.10000000149011612, 'rotate': (99.5, 137.5, -90.0, 137.5), 'curveRes': (8, 5, 3, 1), 'useArm': False, 'af2': 1.0, 'bevelRes': 2, 'autoTaper': True, 'lengthV': (0.0, 0.15000000596046448, 0.25, 0.0), 'armAnim': False, 'prune': False, 'radiusTweak': (1.0, 1.0, 1.0, 1.0), 'leafRotateV': 30.0, 'customShape': (0.8999999761581421, 1.0, 0.20000000298023224, 0.20000000298023224), 'rotateV': (15.0, 0.0, 0.0, 0.0)}

View File

@ -0,0 +1 @@
{'showLeaves': False, 'leafScaleX': 0.20000000298023224, 'horzLeaves': False, 'useArm': False, 'rMode': 'rotate', 'branchDist': 1.5, 'scale': 15.0, 'armLevels': 2, 'gustF': 0.07500000298023224, 'closeTip': False, 'shape': '4', 'minRadius': 0.001500000013038516, 'leafScaleT': 0.0, 'leafDownAngle': 30.0, 'splitByLen': True, 'prunePowerLow': 0.0010000000474974513, 'splitBias': 0.0, 'autoTaper': True, 'leafRotateV': 30.0, 'scale0': 1.0, 'length': (0.75, 0.5, 1.5, 0.10000000149011612), 'lengthV': (0.0, 0.10000000149011612, 0.0, 0.0), 'bevel': True, 'baseSize': 0.20000000298023224, 'handleType': '1', 'ratioPower': 1.75, 'leafScaleV': 0.0, 'ratio': 0.02500000037252903, 'scaleV': 5.0, 'gust': 1.0, 'baseSplits': 2, 'loopFrames': 0, 'curve': (0.0, 20.0, -40.0, 0.0), 'pruneWidth': 0.5, 'shapeS': '4', 'splitAngleV': (0.0, 10.0, 20.0, 0.0), 'branches': (0, 35, 15, 1), 'frameRate': 1.0, 'splitAngle': (12.0, 30.0, 16.0, 0.0), 'seed': 2789, 'nrings': 0, 'previewArm': False, 'pruneWidthPeak': 0.6000000238418579, 'af1': 1.0, 'splitHeight': 0.20000000298023224, 'rotateV': (15.0, 15.0, 45.0, 0.0), 'attractUp': (0.0, 0.0, -2.75, -3.0), 'curveV': (150.0, 120.0, 0.0, 0.0), 'makeMesh': False, 'leaves': 150, 'curveBack': (0.0, 20.0, 0.0, 0.0), 'taper': (1.0, 1.0, 1.0, 1.0), 'resU': 4, 'useOldDownAngle': False, 'pruneRatio': 0.800000011920929, 'levels': 3, 'taperCrown': 0.0, 'attractOut': (0.0, 0.0, 0.0, 0.0), 'leafRotate': 137.5, 'prunePowerHigh': 0.20000000298023224, 'prune': False, 'leafangle': 0.0, 'bevelRes': 1, 'curveRes': (8, 16, 8, 1), 'rotate': (99.5, 137.5, -60.0, 140.0), 'pruneBase': 0.07000000029802322, 'segSplits': (0.10000000149011612, 0.20000000298023224, 0.20000000298023224, 0.0), 'scaleV0': 0.0, 'boneStep': (1, 1, 1, 1), 'useParentAngle': True, 'armAnim': False, 'wind': 1.0, 'leafDist': '10', 'leafScale': 0.25, 'radiusTweak': (1.0, 1.0, 1.0, 1.0), 'leafDownAngleV': 10.0, 'leafAnim': False, 'downAngle': (0.0, 20.0, 30.0, 20.0), 'af2': 1.0, 'af3': 4.0, 'downAngleV': (0.0, 20.0, 10.0, 10.0), 'customShape': (0.5, 1.0, 0.30000001192092896, 0.5), 'leafShape': 'hex', 'rootFlare': 1.0, 'baseSize_s': 0.25}

View File

@ -0,0 +1 @@
{'seed': 0, 'showLeaves': True, 'armLevels': 0, 'leafDist': '6', 'baseSize': 0.3499999940395355, 'loopFrames': 0, 'af3': 4.0, 'previewArm': False, 'leafangle': -45.0, 'useParentAngle': True, 'handleType': '0', 'branches': (0, 60, 30, 10), 'autoTaper': True, 'splitAngle': (12.0, 18.0, 16.0, 0.0), 'baseSize_s': 0.800000011920929, 'closeTip': False, 'af2': 1.0, 'prune': False, 'scale0': 1.0, 'rMode': 'rotate', 'useOldDownAngle': False, 'scaleV0': 0.10000000149011612, 'splitBias': 0.0, 'resU': 2, 'curveBack': (0.0, -5.0, 0.0, 0.0), 'scale': 12.0, 'shape': '8', 'leafDownAngle': 45.0, 'af1': 1.0, 'ratio': 0.019999999552965164, 'horzLeaves': True, 'leafRotate': 137.5, 'minRadius': 0.0020000000949949026, 'bevelRes': 2, 'splitByLen': True, 'rootFlare': 1.149999976158142, 'makeMesh': False, 'downAngleV': (0.0, 25.0, 30.0, 10.0), 'levels': 3, 'scaleV': 2.0, 'armAnim': False, 'lengthV': (0.05000000074505806, 0.20000000298023224, 0.3499999940395355, 0.0), 'pruneWidth': 0.3100000023841858, 'gustF': 0.07500000298023224, 'taper': (1.0, 1.0, 1.0, 1.0), 'splitAngleV': (2.0, 2.0, 0.0, 0.0), 'prunePowerLow': 0.0010000000474974513, 'leafScaleT': 0.20000000298023224, 'leafScaleX': 0.5, 'leafRotateV': 0.0, 'ratioPower': 1.399999976158142, 'segSplits': (0.3499999940395355, 0.3499999940395355, 0.3499999940395355, 0.0), 'downAngle': (90.0, 60.0, 50.0, 45.0), 'rotateV': (0.0, 0.0, 0.0, 0.0), 'gust': 1.0, 'attractUp': (0.0, -1.0, -0.6499999761581421, 0.0), 'leafScaleV': 0.25, 'frameRate': 1.0, 'curveV': (100.0, 80.0, 80.0, 0.0), 'boneStep': (1, 1, 1, 1), 'customShape': (0.699999988079071, 1.0, 0.30000001192092896, 0.5900000333786011), 'pruneBase': 0.30000001192092896, 'leafAnim': False, 'curveRes': (10, 8, 3, 1), 'nrings': 0, 'bevel': True, 'taperCrown': 0.0, 'baseSplits': 2, 'leafShape': 'hex', 'splitHeight': 0.550000011920929, 'wind': 1.0, 'curve': (0.0, -30.0, -25.0, 0.0), 'rotate': (137.5, 137.5, 137.5, 137.5), 'length': (1.0, 0.33000001311302185, 0.375, 0.44999998807907104), 'leafScale': 0.20000000298023224, 'attractOut': (0.0, 0.20000000298023224, 0.25, 0.0), 'prunePowerHigh': 0.10000000149011612, 'branchDist': 1.5, 'useArm': False, 'pruneRatio': 1.0, 'shapeS': '7', 'leafDownAngleV': 10.0, 'pruneWidthPeak': 0.5, 'radiusTweak': (1.0, 1.0, 1.0, 1.0), 'leaves': 16}

View File

@ -1 +0,0 @@
{'pruneWidthPeak': 0.6000000238418579, 'downAngleV': (0.0, -40.0, 10.0, 10.0), 'frameRate': 1.0, 'lengthV': (0.0, 0.05000000074505806, 0.10000000149011612, 0.0), 'shape': '4', 'seed': 0, 'bend': 0.0, 'armAnim': False, 'useArm': False, 'splitAngle': (0.0, 0.0, 0.0, 0.0), 'baseSize': 0.20000000298023224, 'baseSplits': 0, 'scaleV': 5.0, 'scale': 23.0, 'ratio': 0.014999999664723873, 'curveV': (40.0, 90.0, 150.0, 0.0), 'prunePowerHigh': 0.5, 'splitAngleV': (0.0, 0.0, 0.0, 0.0), 'resU': 4, 'segSplits': (0.0, 0.0, 0.0, 0.0), 'ratioPower': 1.2999999523162842, 'handleType': '1', 'length': (1.0, 0.30000001192092896, 0.6000000238418579, 0.4000000059604645), 'rotateV': (0.0, 0.0, 0.0, 0.0), 'attractUp': 0.5, 'scale0': 1.0, 'bevel': False, 'leafDist': '4', 'chooseSet': '0', 'levels': 4, 'downAngle': (90.0, 60.0, 30.0, 45.0), 'showLeaves': False, 'prunePowerLow': 0.0010000000474974513, 'scaleV0': 0.0, 'leafScaleX': 0.5, 'curveRes': (10, 10, 10, 1), 'rotate': (140.0, 140.0, 140.0, 140.0), 'branches': (0, 50, 25, 12), 'prune': False, 'bevelRes': 0, 'taper': (1.0, 1.0, 1.0, 1.0), 'pruneRatio': 1.0, 'leaves': 6, 'curve': (0.0, 0.0, -10.0, 0.0), 'leafScale': 0.30000001192092896, 'windSpeed': 2.0, 'pruneWidth': 0.4000000059604645, 'windGust': 0.0, 'startCurv': 0.0, 'curveBack': (0.0, 0.0, 0.0, 0.0)}

View File

@ -1 +0,0 @@
{'pruneWidthPeak': 0.6000000238418579, 'downAngleV': (0.0, -30.0, 10.0, 10.0), 'frameRate': 1.0, 'lengthV': (0.0, 0.10000000149011612, 0.05000000074505806, 0.0), 'shape': '2', 'seed': 0, 'bend': 0.0, 'armAnim': False, 'useArm': False, 'splitAngle': (10.0, 10.0, 10.0, 0.0), 'baseSize': 0.05000000074505806, 'baseSplits': 2, 'scaleV': 10.0, 'scale': 10.0, 'ratio': 0.017999999225139618, 'curveV': (90.0, 150.0, -30.0, 0.0), 'prunePowerHigh': 0.5, 'splitAngleV': (0.0, 10.0, 10.0, 0.0), 'resU': 4, 'segSplits': (0.4000000059604645, 0.20000000298023224, 0.10000000149011612, 0.0), 'ratioPower': 1.2999999523162842, 'handleType': '1', 'length': (1.0, 0.800000011920929, 0.20000000298023224, 0.4000000059604645), 'rotateV': (0.0, 0.0, 0.0, 0.0), 'attractUp': 0.800000011920929, 'scale0': 1.0, 'bevel': False, 'leafDist': '4', 'chooseSet': '0', 'levels': 3, 'downAngle': (0.0, 30.0, 45.0, 45.0), 'showLeaves': False, 'prunePowerLow': 0.0010000000474974513, 'scaleV0': 0.0, 'leafScaleX': 0.6600000262260437, 'curveRes': (8, 10, 3, 1), 'rotate': (0.0, 80.0, 140.0, 140.0), 'branches': (0, 40, 120, 0), 'prune': False, 'bevelRes': 0, 'taper': (1.0, 1.0, 1.0, 1.0), 'pruneRatio': 1.0, 'leaves': 25, 'curve': (0.0, 40.0, 0.0, 0.0), 'leafScale': 0.11999999731779099, 'windSpeed': 2.0, 'pruneWidth': 0.4000000059604645, 'windGust': 0.0, 'startCurv': 0.0, 'curveBack': (0.0, -70.0, 0.0, 0.0)}

View File

@ -1 +1 @@
{'pruneWidthPeak': 0.6000000238418579, 'downAngleV': (0.0, -50.0, 10.0, 10.0), 'frameRate': 1.0, 'lengthV': (0.0, 0.0, 0.0, 0.0), 'shape': '7', 'seed': 0, 'bend': 0.0, 'armAnim': False, 'useArm': False, 'splitAngle': (0.0, 0.0, 0.0, 0.0), 'baseSize': 0.4000000059604645, 'baseSplits': 0, 'scaleV': 3.0, 'scale': 13.0, 'ratio': 0.014999999664723873, 'curveV': (20.0, 50.0, 75.0, 0.0), 'prunePowerHigh': 0.5, 'splitAngleV': (0.0, 0.0, 0.0, 0.0), 'resU': 4, 'segSplits': (0.0, 0.0, 0.0, 0.0), 'ratioPower': 1.2000000476837158, 'handleType': '1', 'length': (1.0, 0.30000001192092896, 0.6000000238418579, 0.44999998807907104), 'rotateV': (0.0, 0.0, 0.0, 0.0), 'attractUp': 0.5, 'scale0': 1.0, 'bevel': False, 'leafDist': '4', 'chooseSet': '0', 'levels': 3, 'downAngle': (90.0, 60.0, 45.0, 45.0), 'showLeaves': False, 'prunePowerLow': 0.0010000000474974513, 'scaleV0': 0.20000000298023224, 'leafScaleX': 1.0, 'curveRes': (3, 5, 3, 1), 'rotate': (140.0, 140.0, 140.0, 77.0), 'branches': (0, 50, 30, 10), 'prune': False, 'bevelRes': 0, 'taper': (1.0, 1.0, 1.0, 1.0), 'pruneRatio': 1.0, 'leaves': 25, 'curve': (0.0, -40.0, -40.0, 0.0), 'leafScale': 0.17000000178813934, 'windSpeed': 2.0, 'pruneWidth': 0.4000000059604645, 'windGust': 0.0, 'startCurv': 0.0, 'curveBack': (0.0, 0.0, 0.0, 0.0)}
{'leafScale': 0.17000000178813934, 'autoTaper': True, 'customShape': (0.5, 1.0, 0.30000001192092896, 0.5), 'leafShape': 'hex', 'curve': (0.0, -40.0, -40.0, 0.0), 'ratio': 0.014999999664723873, 'splitBias': 0.0, 'pruneWidth': 0.4000000059604645, 'downAngleV': (0.0, 80.0, 10.0, 10.0), 'rotate': (99.5, 137.5, 137.5, 137.5), 'pruneRatio': 1.0, 'leafDownAngle': 45.0, 'makeMesh': False, 'radiusTweak': (1.0, 1.0, 1.0, 1.0), 'rMode': 'rotate', 'splitAngleV': (0.0, 0.0, 0.0, 0.0), 'branchDist': 1.0, 'bevel': False, 'minRadius': 0.001500000013038516, 'prune': False, 'leafRotateV': 0.0, 'splitAngle': (0.0, 0.0, 0.0, 0.0), 'armAnim': False, 'boneStep': (1, 1, 1, 1), 'pruneBase': 0.30000001192092896, 'taperCrown': 0.0, 'baseSplits': 0, 'baseSize_s': 0.25, 'handleType': '0', 'baseSize': 0.4000000059604645, 'af1': 1.0, 'levels': 2, 'leafScaleV': 0.0, 'resU': 4, 'seed': 0, 'downAngle': (90.0, 110.0, 45.0, 45.0), 'leafangle': 0.0, 'scaleV0': 0.10000000149011612, 'prunePowerHigh': 0.5, 'splitByLen': True, 'wind': 1.0, 'shape': '7', 'prunePowerLow': 0.0010000000474974513, 'scale': 13.0, 'leafAnim': False, 'curveBack': (0.0, 0.0, 0.0, 0.0), 'leafScaleX': 1.0, 'horzLeaves': True, 'splitHeight': 0.20000000298023224, 'leafScaleT': 0.0, 'scaleV': 3.0, 'leafDist': '6', 'nrings': 0, 'curveRes': (8, 5, 3, 1), 'shapeS': '4', 'bevelRes': 0, 'useOldDownAngle': False, 'useParentAngle': True, 'armLevels': 2, 'scale0': 1.0, 'taper': (1.0, 1.0, 1.0, 1.0), 'pruneWidthPeak': 0.6000000238418579, 'previewArm': False, 'leaves': 25, 'ratioPower': 1.100000023841858, 'gustF': 0.07500000298023224, 'curveV': (20.0, 50.0, 75.0, 0.0), 'showLeaves': False, 'frameRate': 1.0, 'length': (1.0, 0.30000001192092896, 0.6000000238418579, 0.44999998807907104), 'branches': (0, 50, 30, 10), 'useArm': False, 'loopFrames': 0, 'gust': 1.0, 'af3': 4.0, 'closeTip': False, 'leafRotate': 137.5, 'attractUp': (0.0, 0.0, 0.5, 0.5), 'leafDownAngleV': 10.0, 'rootFlare': 1.0, 'af2': 1.0, 'lengthV': (0.0, 0.0, 0.0, 0.0), 'rotateV': (15.0, 0.0, 0.0, 0.0), 'attractOut': (0.0, 0.0, 0.0, 0.0), 'segSplits': (0.0, 0.0, 0.0, 0.0)}

File diff suppressed because it is too large Load Diff