initial leaf support (need to use in production, at the moment its really simple)

Option to generate variation's - This modifies the original shape to make a variation on the original.
This commit is contained in:
Campbell Barton 2007-11-19 14:00:48 +00:00
parent 0b0542c785
commit 80357d7f28

@ -96,6 +96,14 @@ def freshMesh(mesh):
return mesh
def getObFromName(name):
if name:
try: return bpy.data.objects[name]
except: return None
else:
return None
def closestVecIndex(vec, vecls):
best= -1
@ -121,9 +129,16 @@ class tree:
self.armature = None
self.objectCurve = None
self.objectCurveMat = None
self.objectCurveIMat = None
self.objectTwigBounds = None # use for twigs only at the moment.
self.objectTwigBoundsIMat = None
self.objectTwigBoundsMesh = None
self.objectLeafBounds = None
self.objectLeafBoundsIMat = None
self.objectLeafBoundsMesh = None
self.limbScale = 1.0
self.debug_objects = []
@ -142,6 +157,7 @@ class tree:
# Now calculate the normals
self.objectCurve = objectCurve
self.objectCurveMat = objectCurve.matrixWorld
self.objectCurveIMat = self.objectCurveMat.copy().invert()
curve = objectCurve.data
steps = curve.resolu # curve resolution
@ -201,19 +217,41 @@ class tree:
# Sort from big to small, so big branches get priority
self.branches_all.sort( key = lambda brch: -brch.bpoints[0].radius )
def closestBranchPt(self, co):
best_brch = None
best_pt = None
best_dist = 10000000000
for brch in self.branches_all:
for pt in brch.bpoints:
# if pt.inTwigBounds: # only find twigs, give different results for leaves
l = (pt.co-co).length
if l < best_dist:
best_dist = l
best_brch = brch
best_pt = pt
return best_brch, best_pt
def setTwigBounds(self, objectMesh):
self.objectTwigBounds = objectMesh
self.objectTwigBoundsMesh = objectMesh.getData(mesh=1)
self.objectTwigBoundsIMat = objectMesh.matrixWorld.copy().invert()
#self.objectTwigBoundsIMat = objectMesh.matrixWorld.copy()
for brch in self.branches_all:
brch.calcTwigBounds(self)
def setLeafBounds(self, objectMesh):
self.objectLeafBounds = objectMesh
self.objectLeafBoundsMesh = objectMesh.getData(mesh=1)
self.objectLeafBoundsIMat = objectMesh.matrixWorld.copy().invert()
def isPointInTwigBounds(self, co):
return self.objectTwigBoundsMesh.pointInside(co * self.objectCurveMat * self.objectTwigBoundsIMat)
def isPointInLeafBounds(self, co):
return self.objectLeafBoundsMesh.pointInside(co * self.objectCurveMat * self.objectLeafBoundsIMat)
def resetTags(self, value):
for brch in self.branches_all:
brch.tag = value
@ -223,6 +261,8 @@ class tree:
connect_base_trim = 1.0,\
do_twigs = False,\
twig_ratio = 2.0,\
twig_select_mode = 0,\
twig_select_factor = 0.5,\
twig_scale = 0.8,\
twig_scale_width = 1.0,\
twig_random_orientation = 180,\
@ -238,6 +278,11 @@ class tree:
twig_follow_x=0.0,\
twig_follow_y=0.0,\
twig_follow_z=0.0,\
do_variation = 0,\
variation_seed = 1,\
variation_orientation = 0.0,\
variation_scale = 0.0,\
):
'''
build tree data - fromCurve must run first
@ -284,7 +329,7 @@ class tree:
children = [brch_child for brch_child in pt.children]
if children:
# This pt is one side of the segment, pt.next joins this segment.
# calculate the median point the 2 segments would span
# calculate the median point the 2 segments would spanal
# Once this is done we need to adjust 2 things
# 1) move both segments up/down so they match the branches best.
# 2) set the spacing of the segments around the point.
@ -300,9 +345,38 @@ class tree:
brch.checkPointList()
'''
# Important we so this with existing parent/child but before connecting and calculating verts.
# Variations - use for making multiple versions of the same tree.
if do_variation:
irational_num = 22.0/7.0 # use to make the random number more odd
rnd = [variation_seed]
def next_random_num():
'''
return a random number between 0.0 and 1.0
'''
rnd[0] += (rnd[0] * irational_num) % 1
# prevent
if rnd[0] > 1000000:
rnd[0]-=1000000
return rnd[0] % 1
# Add children temporarily
for brch in self.branches_all:
if brch.parent_pt:
rnd_rot = ((next_random_num() * variation_orientation) - 0.5) * 720
mat_orientation = RotationMatrix(rnd_rot, 3, 'r', brch.parent_pt.no)
rnd_sca = 1 + ((next_random_num()-0.5)* variation_scale )
mat_scale = Matrix([rnd_sca,0,0],[0,rnd_sca,0],[0,0,rnd_sca])
# mat_orientation = RotationMatrix(0, 3, 'r', brch.parent_pt.no)
brch.transformRecursive(self, mat_scale * mat_orientation, brch.parent_pt.co)
# Important we so this with existing parent/child but before connecting and calculating verts.
if do_twigs:
# scale values down
twig_random_orientation= twig_random_orientation/360.0
twig_random_angle= twig_random_angle/360.0
irational_num = 22.0/7.0 # use to make the random number more odd
if twig_ob_bounds: # Only spawn twigs inside this mesh
@ -311,7 +385,7 @@ class tree:
if not twig_recursive:
twig_recursive_limit = 0
self.buildTwigs(twig_ratio)
self.buildTwigs(twig_ratio, twig_select_mode, twig_select_factor)
branches_twig_attached = []
@ -357,7 +431,6 @@ class tree:
if twig_random_angle: rnd2 = (((irational_num * scale * 66666666) % 360) - 180) * twig_random_angle
else: rnd2 = 0.0
# Align this with the existing branch
angle = AngleBetweenVecs(zup, parent_pt.no)
cross = CrossVecs(zup, parent_pt.no)
@ -397,8 +470,8 @@ class tree:
no = Vector()
no.x += twig_follow_x
no.x += twig_follow_y
no.x += twig_follow_z
no.y += twig_follow_y
no.z += twig_follow_z
for i, pt in enumerate(brch_twig.bpoints):
if pt.prev:
@ -529,7 +602,7 @@ class tree:
for brch in self.branches_all:
brch.branchReJoin()
def buildTwigs(self, twig_ratio=1.0):
def buildTwigs(self, twig_ratio, twig_select_mode, twig_select_factor):
ratio_int = int(len(self.branches_all) * twig_ratio)
if ratio_int == 0:
@ -537,6 +610,20 @@ class tree:
# So we only mix branches of similar lengths
branches_sorted = self.branches_all[:]
# Get the branches based on our selection method!
if twig_select_mode==0:
branches_sorted.sort( key = lambda brch: brch.getLength())
elif twig_select_mode==1:
branches_sorted.sort( key = lambda brch:-brch.getLength())
elif twig_select_mode==2:
branches_sorted.sort( key = lambda brch:brch.getStraightness())
elif twig_select_mode==3:
branches_sorted.sort( key = lambda brch:-brch.getStraightness())
factor_int = int(len(self.branches_all) * twig_select_factor)
branches_sorted[factor_int:] = [] # remove the last part of the list
branches_sorted.sort( key = lambda brch: len(brch.bpoints))
branches_new = []
@ -967,7 +1054,8 @@ class tree:
return self.mesh
def toLeafMesh(self, mesh_leaf, leaf_branch_limit = 0.5, leaf_size = 0.5):
def toLeafMesh(self, mesh_leaf, leaf_branch_limit = 0.5, leaf_size = 0.5, leaf_fill=True, leaf_fill_count=1000, leaf_fill_ob_bounds=None):
'''
return a mesh with leaves seperate from the tree
@ -979,80 +1067,151 @@ class tree:
mesh_leaf = freshMesh(mesh_leaf)
self.mesh_leaf = mesh_leaf
totpoints = 0
radius = 0.0
max_radius = 0.0
for brch in self.branches_all:
for pt in brch.bpoints:
radius += pt.radius
if pt.radius > max_radius:
max_radius = pt.radius
# Fill an object with leaves, kind of primitive but useful at times.
if leaf_fill and leaf_fill_count and leaf_fill_ob_bounds:
#totpoints += len(brch.bpoints)
radius_max = max_radius * leaf_branch_limit
verts_extend = []
faces_extend = []
co1,co2,co3,co4 = Vector(),Vector(),Vector(),Vector()
for brch in self.branches_all:
self.setLeafBounds(leaf_fill_ob_bounds)
# quick test, do we need leaves on this branch?
if brch.bpoints[-1].radius > radius_max:
continue
# Get bounds
count = 0
for pt in brch.bpoints:
if pt.childCount == 0 and pt.radius < radius_max:
# Ok we can add a leaf here. set the co's correctly
co1[:] = pt.co
co2[:] = pt.co
co3[:] = pt.co
co4[:] = pt.co
xmin = ymin = zmin = 10000000
xmax = ymax = zmax =-10000000
for v in self.objectLeafBoundsMesh.verts:
x,y,z = tuple(v.co)
if x < xmin: xmin = x
if y < ymin: ymin = y
if z < zmin: zmin = z
if x > xmax: xmax = x
if y > ymax: ymax = y
if z > zmax: zmax = z
verts_extend = []
faces_extend = []
i = leaf_fill_count
while i:
# randomize branch values for leaves for now.
vec = Vector(Rand(xmin, xmax), Rand(ymin, ymax), Rand(zmin, zmax))
if self.objectLeafBoundsMesh.pointInside(vec):
vec = (vec * self.objectLeafBoundsIMat) * self.objectCurveIMat
cross_leafdir = CrossVecs( zup, pt.no )
cross_leafdir.length = leaf_size
# Find the closest branch
brch_close, pt_close = self.closestBranchPt(vec)
no = pt_close.co - vec
#cross = CrossVecs(no, zup)
cross = CrossVecs(no, pt_close.no)
cross.length = leaf_size
vec2 = vec - cross
vec1 = vec + cross
vec3 = vec - cross
vec4 = vec + cross
no_pt = pt_close.no.copy()
no_pt.length = leaf_size
vec3 += no_pt
vec4 += no_pt
'''
no_pt = pt_close.no.copy()
no_pt.length = leaf_size
vec3 += no_pt
vec4 += no_pt
'''
cross
faces_extend.append([len(verts_extend), len(verts_extend)+1, len(verts_extend)+2, len(verts_extend)+3])
verts_extend.extend([vec1, vec2, vec3, vec4])
i-=1
self.mesh_leaf.verts.extend(verts_extend)
self.mesh_leaf.faces.extend(faces_extend)
#cross_leafwidth = CrossVecs(pt.no, cross_leafdir)
# Facing up
cross_leafwidth_up = CrossVecs(zup, cross_leafdir).normalize() * leaf_size
cross_leafwidth_aligned = pt.no
#cross_leafwidth = (cross_leafwidth_up + cross_leafwidth_aligned)/2
cross_leafwidth = cross_leafwidth_aligned
cross_leafwidth.length = leaf_size/2
if count % 2:
cross_leafwidth.negate()
cross_leafdir.negate()
co1 += cross_leafdir
co2 += cross_leafdir
co2 += cross_leafwidth
co3 += cross_leafwidth
co1 -= cross_leafwidth
co4 -= cross_leafwidth
i = len(verts_extend)
faces_extend.append( (i,i+1,i+2,i+3) )
verts_extend.extend([tuple(co1), tuple(co2), tuple(co3), tuple(co4)])
count += 1
self.mesh_leaf.verts.extend(verts_extend)
self.mesh_leaf.faces.extend(faces_extend)
'''
if 0:
totpoints = 0
radius = 0.0
max_radius = 0.0
for brch in self.branches_all:
for pt in brch.bpoints:
radius += pt.radius
if pt.radius > max_radius:
max_radius = pt.radius
#totpoints += len(brch.bpoints)
radius_max = max_radius * leaf_branch_limit
verts_extend = []
faces_extend = []
co1,co2,co3,co4 = Vector(),Vector(),Vector(),Vector()
for brch in self.branches_all:
# quick test, do we need leaves on this branch?
if brch.bpoints[-1].radius > radius_max:
continue
count = 0
for pt in brch.bpoints:
if pt.childCount == 0 and pt.radius < radius_max:
# Ok we can add a leaf here. set the co's correctly
co1[:] = pt.co
co2[:] = pt.co
co3[:] = pt.co
co4[:] = pt.co
cross_leafdir = CrossVecs( zup, pt.no )
cross_leafdir.length = leaf_size
#cross_leafwidth = CrossVecs(pt.no, cross_leafdir)
# Facing up
cross_leafwidth_up = CrossVecs(zup, cross_leafdir).normalize() * leaf_size
cross_leafwidth_aligned = pt.no
#cross_leafwidth = (cross_leafwidth_up + cross_leafwidth_aligned)/2
cross_leafwidth = cross_leafwidth_aligned
cross_leafwidth.length = leaf_size/2
if count % 2:
cross_leafwidth.negate()
cross_leafdir.negate()
co1 += cross_leafdir
co2 += cross_leafdir
co2 += cross_leafwidth
co3 += cross_leafwidth
co1 -= cross_leafwidth
co4 -= cross_leafwidth
i = len(verts_extend)
faces_extend.append( (i,i+1,i+2,i+3) )
verts_extend.extend([tuple(co1), tuple(co2), tuple(co3), tuple(co4)])
count += 1
self.mesh_leaf.verts.extend(verts_extend)
self.mesh_leaf.faces.extend(faces_extend)
'''
return self.mesh_leaf
def toArmature(self, ob_arm, armature):
@ -1617,10 +1776,18 @@ class branch:
else:
return 0.8
def getLength(self):
return (self.bpoints[0].co - self.bpoints[-1].co).length
def getStraightness(self):
straight = 0.0
pt = self.bpoints[0]
while pt.next:
straight += AngleBetweenVecs(pt.no, pt.next.no)
pt = pt.next
return straight
'''
def calcTotChildren(self):
for pt in self.bpoints:
@ -1658,8 +1825,6 @@ class branch:
#if pt.inTwigBounds:
# debug_pt(pt.co)
def baseTrim(self, connect_base_trim):
# if 1) dont remove the whole branch, maybe an option but later
# if 2) we are alredy a parent, cant remove me now.... darn :/ not nice...
@ -1677,8 +1842,6 @@ class branch:
del self.bpoints[0]
self.bpoints[0].prev = None
def boundsTrim(self):
'''
@ -1809,6 +1972,29 @@ class branch:
for pt in self.bpoints:
pt.co -= ofs
def transformRecursive(self, tree, mat3x3, cent, scale=None):
if scale==None:
# incase this is a translation matrix
scale = ((xyzup * mat3x3) - (Vector(0,0,0) * mat3x3)).length
for pt in self.bpoints: pt.co = ((pt.co-cent) * mat3x3) + cent
#for pt in self.bpoints: pt.co = (pt.co * mat3x3)
for pt in self.bpoints: self.calcPointExtras()
for brch in tree.branches_all:
if brch.parent_pt:
if brch.parent_pt.branch == self:
brch.transformRecursive(tree, mat3x3, cent, scale)
'''
for pt in self.bpoints:
for brch in pt.children:
if brch:
brch.transformRecursive(mat3x3, cent, scale)
'''
def bestTwigSegment(self):
'''
Return the most free part on the branch to place a new twig
@ -2109,7 +2295,7 @@ PREFS['image_main'] = Draw.Create('')
PREFS['do_uv'] = Draw.Create(0)
PREFS['uv_x_scale'] = Draw.Create(4.0)
PREFS['uv_y_scale'] = Draw.Create(1.0)
PREFS['do_material'] = Draw.Create(1)
PREFS['do_material'] = Draw.Create(0)
PREFS['material_use_existing'] = Draw.Create(1)
PREFS['material_texture'] = Draw.Create(1)
PREFS['material_stencil'] = Draw.Create(1)
@ -2130,6 +2316,8 @@ PREFS['anim_offset_scale'] = Draw.Create(1.0)
PREFS['do_twigs'] = Draw.Create(0)
PREFS['twig_ratio'] = Draw.Create(2.0)
PREFS['twig_select_mode'] = Draw.Create(0)
PREFS['twig_select_factor'] = Draw.Create(0.5)
PREFS['twig_scale'] = Draw.Create(0.8)
PREFS['twig_scale_width'] = Draw.Create(1.0)
PREFS['twig_random_orientation'] = Draw.Create(180)
@ -2146,10 +2334,19 @@ PREFS['twig_follow_x'] = Draw.Create(0.0)
PREFS['twig_follow_y'] = Draw.Create(0.0)
PREFS['twig_follow_z'] = Draw.Create(0.0)
PREFS['do_leaf'] = Draw.Create(1)
PREFS['do_leaf'] = Draw.Create(0)
PREFS['leaf_fill'] = Draw.Create(1)
PREFS['leaf_fill_count'] = Draw.Create(1000)
PREFS['leaf_fill_ob_bounds'] = Draw.Create('')
PREFS['leaf_branch_limit'] = Draw.Create(0.25)
PREFS['leaf_size'] = Draw.Create(0.5)
PREFS['do_variation'] = Draw.Create(0)
PREFS['variation_seed'] = Draw.Create(1)
PREFS['variation_orientation'] = Draw.Create(0.0)
PREFS['variation_scale'] = Draw.Create(0.0)
GLOBAL_PREFS = {}
GLOBAL_PREFS['realtime_update'] = Draw.Create(0)
@ -2227,7 +2424,7 @@ def buildTree(ob_curve, single=False):
def newObChild(parent, obdata):
ob_new = bpy.data.scenes.active.objects.new(obdata)
ob_new.Layers = parent.Layers
# ob_new.Layers = parent.Layers
# new object settings
parent.makeParent([ob_new])
@ -2271,18 +2468,15 @@ def buildTree(ob_curve, single=False):
print '\tconnecting branches...',
twig_ob_bounds = PREFS['twig_ob_bounds'].val
if twig_ob_bounds:
try: twig_ob_bounds = bpy.data.objects[twig_ob_bounds]
except: twig_ob_bounds = None
else:
twig_ob_bounds = None
twig_ob_bounds = getObFromName(PREFS['twig_ob_bounds'].val)
t.buildConnections(\
sloppy = PREFS['connect_sloppy'].val,\
connect_base_trim = PREFS['connect_base_trim'].val,\
do_twigs = PREFS['do_twigs'].val,\
twig_ratio = PREFS['twig_ratio'].val,\
twig_select_mode = PREFS['twig_select_mode'].val,\
twig_select_factor = PREFS['twig_select_factor'].val,\
twig_scale = PREFS['twig_scale'].val,\
twig_scale_width = PREFS['twig_scale_width'].val,\
twig_random_orientation = PREFS['twig_random_orientation'].val,\
@ -2298,8 +2492,13 @@ def buildTree(ob_curve, single=False):
twig_follow_x = PREFS['twig_follow_x'].val,\
twig_follow_y = PREFS['twig_follow_y'].val,\
twig_follow_z = PREFS['twig_follow_z'].val,\
do_variation = PREFS['do_variation'].val,\
variation_seed = PREFS['variation_seed'].val,\
variation_orientation = PREFS['variation_orientation'].val,\
variation_scale = PREFS['variation_scale'].val,\
)
time4 = Blender.sys.time() # time print
print '%.4f sec' % (time4-time3)
print '\toptimizing point spacing...',
@ -2345,21 +2544,27 @@ def buildTree(ob_curve, single=False):
do_uv_blend_layer = do_uv_blend_layer,\
do_cap_ends = PREFS['do_cap_ends'].val
)
"""
if PREFS['do_leaf'].val:
ob_leaf = getObChild(ob_mesh, 'Mesh')
if not ob_leaf: # New object
mesh_leaf = bpy.data.meshes.new('tree_' + ob_curve.name)
mesh_leaf = bpy.data.meshes.new('leaf_' + ob_curve.name)
ob_leaf = newObChild(ob_mesh, mesh_leaf)
else:
mesh_leaf = ob_leaf.getData(mesh=1)
ob_leaf.setMatrix(Matrix())
leaf_fill_ob_bounds = getObFromName(PREFS['leaf_fill_ob_bounds'].val)
print "LEAF!!!"
mesh_leaf = t.toLeafMesh(mesh_leaf,\
leaf_branch_limit = PREFS['leaf_branch_limit'].val,\
leaf_size = PREFS['leaf_size'].val,\
leaf_fill = PREFS['leaf_fill'].val,\
leaf_fill_count = PREFS['leaf_fill_count'].val,\
leaf_fill_ob_bounds = leaf_fill_ob_bounds,\
)
"""
mesh.calcNormals()
if PREFS['do_material'].val:
@ -2460,22 +2665,30 @@ def buildTree(ob_curve, single=False):
#mesh.update()
bpy.data.scenes.active.update()
def do_pref_read(e,v):
def do_pref_read(e=0,v=0, quiet=False):
'''
We dont care about e and v values, only there because its a callback
'''
sce = bpy.data.scenes.active
ob = sce.objects.active
if not ob:
Blender.Draw.PupMenu('No active curve object')
if not quiet:
Blender.Draw.PupMenu('No active curve object')
return
if ob.type != 'Curve':
ob = ob.parent
if ob.type != 'Curve':
Blender.Draw.PupMenu('No active curve object')
if not quiet:
Blender.Draw.PupMenu('No active curve object')
return
if not IDProp2Prefs(ob.properties, PREFS):
Blender.Draw.PupMenu('Curve object has no settings stored on it')
if not quiet:
Blender.Draw.PupMenu('Curve object has no settings stored on it')
return
Blender.Draw.Redraw()
@ -2602,41 +2815,8 @@ def gui():
xtmp = x
# ---------- ---------- ---------- ----------
Blender.Draw.BeginAlign()
PREFS['do_cap_ends'] = Draw.Toggle('Cap Ends',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['do_cap_ends'].val, 'Add faces onto branch endpoints'); xtmp += but_width*2;
PREFS['do_subsurf'] = Draw.Toggle('SubSurf',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['do_subsurf'].val, 'Enable subsurf for newly generated objects'); xtmp += but_width*2;
Blender.Draw.EndAlign()
y-=but_height+MARGIN
xtmp = x
# ---------- ---------- ---------- ----------
Blender.Draw.BeginAlign()
PREFS['seg_density'] = Draw.Number('Segment Spacing',EVENT_UPDATE, xtmp, y, but_width*4, but_height, PREFS['seg_density'].val, 0.05, 10.0, 'Scale the limit points collapse, that are closer then the branch width'); xtmp += but_width*4;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['seg_density_angle'] = Draw.Number('Angle Spacing', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_density_angle'].val, 0.0, 180.0, 'Segments above this angle will not collapse (lower value for more detail)'); xtmp += but_width*2;
PREFS['seg_density_radius'] = Draw.Number('Radius Spacing', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_density_radius'].val, 0.0, 1.0, 'Segments above this difference in radius will not collapse (lower value for more detail)'); xtmp += but_width*2;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['seg_joint_compression'] = Draw.Number('Joint Width', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_joint_compression'].val, 0.1, 2.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
PREFS['seg_joint_smooth'] = Draw.Number('Joint Smooth', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_joint_smooth'].val, 0.0, 1.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['connect_sloppy'] = Draw.Number('Connect Limit',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['connect_sloppy'].val, 0.1, 2.0, 'Strictness when connecting branches'); xtmp += but_width*2;
PREFS['connect_base_trim'] = Draw.Number('Trim Base', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['connect_base_trim'].val, 0.0, 2.0, 'Trim branch base to better connect with parent branch'); xtmp += but_width*2;
Blender.Draw.EndAlign()
y-=but_height+MARGIN
xtmp = x
# ---------- ---------- ---------- ----------
Blender.Draw.BeginAlign()
PREFS['do_twigs'] = Draw.Toggle('Generate Twigs',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['do_twigs'].val, 'Generate child branches based existing branches'); xtmp += but_width*2;
@ -2646,6 +2826,12 @@ def gui():
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['twig_select_mode'] = Draw.Menu('Branch Selection Method%t|From Short%x0|From Long%x1|From Straight%x2|From Bent%x3|',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['twig_select_mode'].val, 'Select branches to use as twigs based on this attribute'); xtmp += but_width*2;
PREFS['twig_select_factor'] = Draw.Number('From Factor', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_select_factor'].val, 0.0, 16, 'Select branches, lower value is more strict and will give you less variation'); xtmp += but_width*2;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['twig_recursive'] = Draw.Toggle('Recursive Twigs',EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['twig_recursive'].val, 'Recursively add twigs into eachother'); xtmp += but_width*2;
PREFS['twig_recursive_limit'] = Draw.Number('Generations', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['twig_recursive_limit'].val, 0.0, 16, 'Number of generations allowed, 0 is inf'); xtmp += but_width*2;
@ -2706,7 +2892,6 @@ def gui():
"""
Blender.Draw.BeginAlign()
if PREFS['do_leaf'].val == 0:
but_width_tmp = but_width*2
@ -2719,37 +2904,30 @@ def gui():
y-=but_height
xtmp = x
PREFS['leaf_branch_limit'] = Draw.Number('Branch Limit', EVENT_UPDATE, xtmp, y, but_width*4, but_height, PREFS['leaf_branch_limit'].val, 0.1, 2.0, 'Maximum thichness where a branch can bare leaves'); xtmp += but_width*4;
# Dont use yet
# PREFS['leaf_branch_limit'] = Draw.Number('Branch Limit', EVENT_UPDATE, xtmp, y, but_width*4, but_height, PREFS['leaf_branch_limit'].val, 0.1, 2.0, 'Maximum thichness where a branch can bare leaves'); xtmp += but_width*4;
'''
PREFS['do_uv_uscale'] = Draw.Toggle('U-Scale', EVENT_UPDATE, xtmp, y, but_width, but_height, PREFS['do_uv_uscale'].val, 'Scale the width according to the face size (will NOT tile)'); xtmp += but_width;
PREFS['do_uv_keep_vproportion'] = Draw.Toggle('V-Aspect', EVENT_UPDATE, xtmp, y, but_width, but_height, PREFS['do_uv_keep_vproportion'].val, 'Correct the UV aspect with the branch width'); xtmp += but_width;
PREFS['do_uv_vnormalize'] = Draw.Toggle('V-Normaize', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['do_uv_vnormalize'].val, 'Scale the UVs to fit onto the image verticaly'); xtmp += but_width*2;
if PREFS['leaf_fill'].val == 0:
but_width_tmp = but_width*2
else:
but_width_tmp = but_width*4
PREFS['leaf_fill'] = Draw.Toggle('Fill Object', EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['leaf_fill'].val, 'Fill an object with leaves'); xtmp += but_width*2;
if PREFS['leaf_fill'].val:
PREFS['leaf_fill_ob_bounds'] = Draw.String('OB Bound: ', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_fill_ob_bounds'].val, 64, 'Fill this object with leaves', do_ob_check); xtmp += but_width*2;
# ---------- ---------- ---------- ----------
y-=but_height
xtmp = x
PREFS['leaf_fill_count'] = Draw.Number('Fill #', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_fill_count'].val, 10, 100000, 'Number of leaves to fill in'); xtmp += but_width*2;
PREFS['leaf_size'] = Draw.Number('Size', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['leaf_size'].val, 0.001, 10.0, 'size of the leaf'); xtmp += but_width*2;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['uv_x_scale'] = Draw.Number('Scale U', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['uv_x_scale'].val, 0.01, 10.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
PREFS['uv_y_scale'] = Draw.Number('Scale V', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['uv_y_scale'].val, 0.01, 10.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['image_main'] = Draw.String('IM: ', EVENT_UPDATE, xtmp, y, but_width*3, but_height, PREFS['image_main'].val, 64, 'Image to apply to faces'); xtmp += but_width*3;
Draw.PushButton('Use Active', EVENT_UPDATE, xtmp, y, but_width, but_height, 'Get the image from the active image window', do_active_image); xtmp += but_width;
'''
Blender.Draw.EndAlign()
y-=but_height+MARGIN
xtmp = x
# ---------- ---------- ---------- ----------
"""
Blender.Draw.BeginAlign()
@ -2804,7 +2982,13 @@ def gui():
# ---------- ---------- ---------- ----------
Blender.Draw.BeginAlign()
PREFS['do_armature'] = Draw.Toggle('Generate Armature & Skin Mesh', EVENT_UPDATE_AND_UI, xtmp, y, but_width*4, but_height, PREFS['do_armature'].val, 'Generate Armatuer'); xtmp += but_width*4;
if PREFS['do_armature'].val == 0:
but_width_tmp = but_width*2
else:
but_width_tmp = but_width*4
Blender.Draw.BeginAlign()
PREFS['do_armature'] = Draw.Toggle('Generate Motion', EVENT_UPDATE_AND_UI, xtmp, y, but_width_tmp, but_height, PREFS['do_armature'].val, 'Generate Armatuer animation and apply to branches'); xtmp += but_width_tmp;
# ---------- ---------- ---------- ----------
if PREFS['do_armature'].val:
@ -2840,6 +3024,67 @@ def gui():
xtmp = x
# ---------- ---------- ---------- ----------
Blender.Draw.BeginAlign()
PREFS['do_variation'] = Draw.Toggle('Generate Variation', EVENT_UPDATE_AND_UI, xtmp, y, but_width*2, but_height, PREFS['do_variation'].val, 'Create a variant by moving the branches'); xtmp += but_width*2;
# ---------- ---------- ---------- ----------
if PREFS['do_variation'].val:
PREFS['variation_seed'] = Draw.Number('Rand Seed', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['variation_seed'].val, 1, 100000, 'Change this to get a different variation'); xtmp += but_width*2;
y-=but_height
xtmp = x
PREFS['variation_orientation'] = Draw.Number('Orientation', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['variation_orientation'].val, 0, 1.0, 'Randomize rotation of the branch around its parent'); xtmp += but_width*2;
PREFS['variation_scale'] = Draw.Number('Scale', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['variation_scale'].val, 0.0, 1.0, 'Randomize the scale of branches'); xtmp += but_width*2;
Blender.Draw.EndAlign()
y-=but_height+(MARGIN*2)
xtmp = x
# ---------- ---------- ---------- ----------
Blender.Draw.BeginAlign()
PREFS['seg_density'] = Draw.Number('Segment Spacing',EVENT_UPDATE, xtmp, y, but_width*4, but_height, PREFS['seg_density'].val, 0.05, 10.0, 'Scale the limit points collapse, that are closer then the branch width'); xtmp += but_width*4;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['seg_density_angle'] = Draw.Number('Angle Spacing', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_density_angle'].val, 0.0, 180.0, 'Segments above this angle will not collapse (lower value for more detail)'); xtmp += but_width*2;
PREFS['seg_density_radius'] = Draw.Number('Radius Spacing', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_density_radius'].val, 0.0, 1.0, 'Segments above this difference in radius will not collapse (lower value for more detail)'); xtmp += but_width*2;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['seg_joint_compression'] = Draw.Number('Joint Width', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_joint_compression'].val, 0.1, 2.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
PREFS['seg_joint_smooth'] = Draw.Number('Joint Smooth', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['seg_joint_smooth'].val, 0.0, 1.0, 'Edge loop spacing around branch join, lower value for less webed joins'); xtmp += but_width*2;
y-=but_height
xtmp = x
# ---------- ---------- ---------- ----------
PREFS['connect_sloppy'] = Draw.Number('Connect Limit',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['connect_sloppy'].val, 0.1, 2.0, 'Strictness when connecting branches'); xtmp += but_width*2;
PREFS['connect_base_trim'] = Draw.Number('Trim Base', EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['connect_base_trim'].val, 0.0, 2.0, 'Trim branch base to better connect with parent branch'); xtmp += but_width*2;
Blender.Draw.EndAlign()
y-=but_height+MARGIN
xtmp = x
# ---------- ---------- ---------- ----------
Blender.Draw.BeginAlign()
PREFS['do_cap_ends'] = Draw.Toggle('Cap Ends',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['do_cap_ends'].val, 'Add faces onto branch endpoints'); xtmp += but_width*2;
PREFS['do_subsurf'] = Draw.Toggle('SubSurf',EVENT_UPDATE, xtmp, y, but_width*2, but_height, PREFS['do_subsurf'].val, 'Enable subsurf for newly generated objects'); xtmp += but_width*2;
Blender.Draw.EndAlign()
y-=but_height+MARGIN
xtmp = x
# ---------- ---------- ---------- ----------
Blender.Draw.BeginAlign()
Draw.PushButton('Read Active Prefs', EVENT_REDRAW, xtmp, y, but_width*2, but_height, 'Read the ID Property settings from the active curve object', do_pref_read); xtmp += but_width*2;
@ -2869,4 +3114,7 @@ def gui():
if __name__ == '__main__':
# Read the active objects prefs on load. if they exist
do_pref_read(quiet=True)
Draw.Register(gui, evt, bevt)