Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-11-19 20:19:08 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-11-19 20:19:08 +0400
commit9ac0a714bee5df2153e0a73bb55962139ba18eb2 (patch)
tree029104d14b7e942dd616bf8443e09d0461ac6350 /add_curve_sapling
parent5e44117da5a35882e7f3919f4c48c234acebe045 (diff)
indentation edits and copy pyrimid from contrib (where I had made some edits), removed so this wont happen again.
Diffstat (limited to 'add_curve_sapling')
-rw-r--r--add_curve_sapling/utils.py944
1 files changed, 472 insertions, 472 deletions
diff --git a/add_curve_sapling/utils.py b/add_curve_sapling/utils.py
index 16a4509e..f74fcef3 100644
--- a/add_curve_sapling/utils.py
+++ b/add_curve_sapling/utils.py
@@ -402,369 +402,369 @@ def genLeafMesh(leafScale,leafScaleX,loc,quat,index,downAngle,downAngleV,rotate,
return vertsList,facesList,oldRot
def addTree(props):
- global splitError
- #startTime = time.time()
- # Set the seed for repeatable results
- seed(props.seed)#
-
- # Set all other variables
- levels = props.levels#
- length = props.length#
- lengthV = props.lengthV#
- branches = props.branches#
- curveRes = props.curveRes#
- curve = toRad(props.curve)#
- curveV = toRad(props.curveV)#
- curveBack = toRad(props.curveBack)#
- baseSplits = props.baseSplits#
- segSplits = props.segSplits#
- splitAngle = toRad(props.splitAngle)#
- splitAngleV = toRad(props.splitAngleV)#
- scale = props.scale#
- scaleV = props.scaleV#
- attractUp = props.attractUp#
- shape = int(props.shape)#
- baseSize = props.baseSize
- ratio = props.ratio
- taper = props.taper#
- ratioPower = props.ratioPower#
- downAngle = toRad(props.downAngle)#
- downAngleV = toRad(props.downAngleV)#
- rotate = toRad(props.rotate)#
- rotateV = toRad(props.rotateV)#
- scale0 = props.scale0#
- scaleV0 = props.scaleV0#
- prune = props.prune#
- pruneWidth = props.pruneWidth#
- pruneWidthPeak = props.pruneWidthPeak#
- prunePowerLow = props.prunePowerLow#
- prunePowerHigh = props.prunePowerHigh#
- pruneRatio = props.pruneRatio#
- leafScale = props.leafScale#
- leafScaleX = props.leafScaleX#
- leafShape = props.leafShape
- bend = props.bend#
- leafDist = int(props.leafDist)#
- bevelRes = props.bevelRes#
- resU = props.resU#
- useArm = props.useArm
-
- frameRate = props.frameRate
- windSpeed = props.windSpeed
- windGust = props.windGust
- armAnim = props.armAnim
-
- leafObj = None
-
- # Some effects can be turned ON and OFF, the necessary variables are changed here
- if not props.bevel:
- bevelDepth = 0.0
- else:
- bevelDepth = 1.0
-
- if not props.showLeaves:
- leaves = 0
- else:
- leaves = props.leaves
-
- if props.handleType == '0':
- handles = 'AUTO'
- else:
- handles = 'VECTOR'
+ global splitError
+ #startTime = time.time()
+ # Set the seed for repeatable results
+ seed(props.seed)#
+
+ # Set all other variables
+ levels = props.levels#
+ length = props.length#
+ lengthV = props.lengthV#
+ branches = props.branches#
+ curveRes = props.curveRes#
+ curve = toRad(props.curve)#
+ curveV = toRad(props.curveV)#
+ curveBack = toRad(props.curveBack)#
+ baseSplits = props.baseSplits#
+ segSplits = props.segSplits#
+ splitAngle = toRad(props.splitAngle)#
+ splitAngleV = toRad(props.splitAngleV)#
+ scale = props.scale#
+ scaleV = props.scaleV#
+ attractUp = props.attractUp#
+ shape = int(props.shape)#
+ baseSize = props.baseSize
+ ratio = props.ratio
+ taper = props.taper#
+ ratioPower = props.ratioPower#
+ downAngle = toRad(props.downAngle)#
+ downAngleV = toRad(props.downAngleV)#
+ rotate = toRad(props.rotate)#
+ rotateV = toRad(props.rotateV)#
+ scale0 = props.scale0#
+ scaleV0 = props.scaleV0#
+ prune = props.prune#
+ pruneWidth = props.pruneWidth#
+ pruneWidthPeak = props.pruneWidthPeak#
+ prunePowerLow = props.prunePowerLow#
+ prunePowerHigh = props.prunePowerHigh#
+ pruneRatio = props.pruneRatio#
+ leafScale = props.leafScale#
+ leafScaleX = props.leafScaleX#
+ leafShape = props.leafShape
+ bend = props.bend#
+ leafDist = int(props.leafDist)#
+ bevelRes = props.bevelRes#
+ resU = props.resU#
+ useArm = props.useArm
+
+ frameRate = props.frameRate
+ windSpeed = props.windSpeed
+ windGust = props.windGust
+ armAnim = props.armAnim
+
+ leafObj = None
+
+ # Some effects can be turned ON and OFF, the necessary variables are changed here
+ if not props.bevel:
+ bevelDepth = 0.0
+ else:
+ bevelDepth = 1.0
- for ob in bpy.data.objects:
- ob.select = False
+ if not props.showLeaves:
+ leaves = 0
+ else:
+ leaves = props.leaves
- childP = []
- stemList = []
-
- # Initialise the tree object and curve and adjust the settings
- cu = bpy.data.curves.new('tree','CURVE')
- treeOb = bpy.data.objects.new('tree',cu)
- bpy.context.scene.objects.link(treeOb)
-
- cu.dimensions = '3D'
- cu.fill_mode = 'FULL'
- cu.bevel_depth = bevelDepth
- cu.bevel_resolution = bevelRes
-
- # Fix the scale of the tree now
- scaleVal = scale + uniform(-scaleV,scaleV)
-
- # If pruning is turned on we need to draw the pruning envelope
- if prune:
- enHandle = 'VECTOR'
- enNum = 128
- enCu = bpy.data.curves.new('envelope','CURVE')
- enOb = bpy.data.objects.new('envelope',enCu)
- enOb.parent = treeOb
- bpy.context.scene.objects.link(enOb)
- newSpline = enCu.splines.new('BEZIER')
+ if props.handleType == '0':
+ handles = 'AUTO'
+ else:
+ handles = 'VECTOR'
+
+ for ob in bpy.data.objects:
+ ob.select = False
+
+ childP = []
+ stemList = []
+
+ # Initialise the tree object and curve and adjust the settings
+ cu = bpy.data.curves.new('tree','CURVE')
+ treeOb = bpy.data.objects.new('tree',cu)
+ bpy.context.scene.objects.link(treeOb)
+
+ cu.dimensions = '3D'
+ cu.fill_mode = 'FULL'
+ cu.bevel_depth = bevelDepth
+ cu.bevel_resolution = bevelRes
+
+ # Fix the scale of the tree now
+ scaleVal = scale + uniform(-scaleV,scaleV)
+
+ # If pruning is turned on we need to draw the pruning envelope
+ if prune:
+ enHandle = 'VECTOR'
+ enNum = 128
+ enCu = bpy.data.curves.new('envelope','CURVE')
+ enOb = bpy.data.objects.new('envelope',enCu)
+ enOb.parent = treeOb
+ bpy.context.scene.objects.link(enOb)
+ newSpline = enCu.splines.new('BEZIER')
+ newPoint = newSpline.bezier_points[-1]
+ newPoint.co = Vector((0,0,scaleVal))
+ (newPoint.handle_right_type,newPoint.handle_left_type) = (enHandle,enHandle)
+ # Set the coordinates by varying the z value, envelope will be aligned to the x-axis
+ for c in range(enNum):
+ newSpline.bezier_points.add()
newPoint = newSpline.bezier_points[-1]
- newPoint.co = Vector((0,0,scaleVal))
+ ratioVal = (c+1)/(enNum)
+ zVal = scaleVal - scaleVal*(1-baseSize)*ratioVal
+ newPoint.co = Vector((scaleVal*pruneWidth*shapeRatio(8,ratioVal,pruneWidthPeak,prunePowerHigh,prunePowerLow),0,zVal))
(newPoint.handle_right_type,newPoint.handle_left_type) = (enHandle,enHandle)
- # Set the coordinates by varying the z value, envelope will be aligned to the x-axis
- for c in range(enNum):
- newSpline.bezier_points.add()
- newPoint = newSpline.bezier_points[-1]
- ratioVal = (c+1)/(enNum)
- zVal = scaleVal - scaleVal*(1-baseSize)*ratioVal
- newPoint.co = Vector((scaleVal*pruneWidth*shapeRatio(8,ratioVal,pruneWidthPeak,prunePowerHigh,prunePowerLow),0,zVal))
- (newPoint.handle_right_type,newPoint.handle_left_type) = (enHandle,enHandle)
- newSpline = enCu.splines.new('BEZIER')
+ newSpline = enCu.splines.new('BEZIER')
+ newPoint = newSpline.bezier_points[-1]
+ newPoint.co = Vector((0,0,scaleVal))
+ (newPoint.handle_right_type,newPoint.handle_left_type) = (enHandle,enHandle)
+ # Create a second envelope but this time on the y-axis
+ for c in range(enNum):
+ newSpline.bezier_points.add()
newPoint = newSpline.bezier_points[-1]
- newPoint.co = Vector((0,0,scaleVal))
+ ratioVal = (c+1)/(enNum)
+ zVal = scaleVal - scaleVal*(1-baseSize)*ratioVal
+ newPoint.co = Vector((0,scaleVal*pruneWidth*shapeRatio(8,ratioVal,pruneWidthPeak,prunePowerHigh,prunePowerLow),zVal))
(newPoint.handle_right_type,newPoint.handle_left_type) = (enHandle,enHandle)
- # Create a second envelope but this time on the y-axis
- for c in range(enNum):
- newSpline.bezier_points.add()
- newPoint = newSpline.bezier_points[-1]
- ratioVal = (c+1)/(enNum)
- zVal = scaleVal - scaleVal*(1-baseSize)*ratioVal
- newPoint.co = Vector((0,scaleVal*pruneWidth*shapeRatio(8,ratioVal,pruneWidthPeak,prunePowerHigh,prunePowerLow),zVal))
- (newPoint.handle_right_type,newPoint.handle_left_type) = (enHandle,enHandle)
-
- leafVerts = []
- leafFaces = []
- levelCount = []
-
- splineToBone = deque([''])
- addsplinetobone = splineToBone.append
-
- # Each of the levels needed by the user we grow all the splines
- for n in range(levels):
- storeN = n
- stemList = deque()
- addstem = stemList.append
- # If n is used as an index to access parameters for the tree it must be at most 3 or it will reference outside the array index
- n = min(3,n)
- vertAtt = attractUp
- splitError = 0.0
- # If this is the first level of growth (the trunk) then we need some special work to begin the tree
- if n == 0:
- vertAtt = 0.0
+
+ leafVerts = []
+ leafFaces = []
+ levelCount = []
+
+ splineToBone = deque([''])
+ addsplinetobone = splineToBone.append
+
+ # Each of the levels needed by the user we grow all the splines
+ for n in range(levels):
+ storeN = n
+ stemList = deque()
+ addstem = stemList.append
+ # If n is used as an index to access parameters for the tree it must be at most 3 or it will reference outside the array index
+ n = min(3,n)
+ vertAtt = attractUp
+ splitError = 0.0
+ # If this is the first level of growth (the trunk) then we need some special work to begin the tree
+ if n == 0:
+ vertAtt = 0.0
+ newSpline = cu.splines.new('BEZIER')
+ cu.resolution_u = resU
+ newPoint = newSpline.bezier_points[-1]
+ newPoint.co = Vector((0,0,0))
+ newPoint.handle_right = Vector((0,0,1))
+ newPoint.handle_left = Vector((0,0,-1))
+ #(newPoint.handle_right_type,newPoint.handle_left_type) = ('VECTOR','VECTOR')
+ branchL = (scaleVal)*(length[0] + uniform(-lengthV[0],lengthV[0]))
+ childStems = branches[1]
+ startRad = branchL*ratio*(scale0 + uniform(-scaleV0,scaleV0))
+ endRad = startRad*(1 - taper[0])
+ newPoint.radius = startRad
+ addstem(stemSpline(newSpline,curve[0]/curveRes[0],curveV[0]/curveRes[0],0,curveRes[0],branchL/curveRes[0],childStems,startRad,endRad,0))
+ # If this isn't the trunk then we may have multiple stem to intialise
+ else:
+ # Store the old rotation to allow new stems to be rotated away from the previous one.
+ oldRotate = 0
+ # For each of the points defined in the list of stem starting points we need to grow a stem.
+ for p in childP:
+ # Add a spline and set the coordinate of the first point.
newSpline = cu.splines.new('BEZIER')
cu.resolution_u = resU
newPoint = newSpline.bezier_points[-1]
- newPoint.co = Vector((0,0,0))
- newPoint.handle_right = Vector((0,0,1))
- newPoint.handle_left = Vector((0,0,-1))
- #(newPoint.handle_right_type,newPoint.handle_left_type) = ('VECTOR','VECTOR')
- branchL = (scaleVal)*(length[0] + uniform(-lengthV[0],lengthV[0]))
- childStems = branches[1]
- startRad = branchL*ratio*(scale0 + uniform(-scaleV0,scaleV0))
- endRad = startRad*(1 - taper[0])
+ newPoint.co = p.co
+ tempPos = zAxis.copy()
+ # If the -ve flag for downAngle is used we need a special formula to find it
+ if downAngleV[n] < 0.0:
+ downV = downAngleV[n]*(1 - 2*shapeRatio(0,(p.lengthPar - p.offset)/(p.lengthPar - baseSize*scaleVal)))
+ random()
+ # Otherwise just find a random value
+ else:
+ downV = uniform(-downAngleV[n],downAngleV[n])
+ downRotMat = Matrix.Rotation(downAngle[n]+downV,3,'X')
+ tempPos.rotate(downRotMat)
+ # If the -ve flag for rotate is used we need to find which side of the stem the last child point was and then grow in the opposite direction.
+ if rotate[n] < 0.0:
+ oldRotate = -copysign(rotate[n] + uniform(-rotateV[n],rotateV[n]),oldRotate)
+ # Otherwise just generate a random number in the specified range
+ else:
+ oldRotate += rotate[n]+uniform(-rotateV[n],rotateV[n])
+ # Rotate the direction of growth and set the new point coordinates
+ rotMat = Matrix.Rotation(oldRotate,3,'Z')
+ tempPos.rotate(rotMat)
+ tempPos.rotate(p.quat)
+ newPoint.handle_right = p.co + tempPos
+ # If this is the first level of branching then upward attraction has no effect and a special formula is used to find branch length and the number of child stems
+ if n == 1:
+ vertAtt = 0.0
+ lMax = length[1] + uniform(-lengthV[1],lengthV[1])
+ branchL = p.lengthPar*lMax*shapeRatio(shape,(p.lengthPar - p.offset)/(p.lengthPar - baseSize*scaleVal))
+ childStems = branches[2]*(0.2 + 0.8*(branchL/p.lengthPar)/lMax)
+ elif storeN <= levels - 2:
+ branchL = (length[n] + uniform(-lengthV[n],lengthV[n]))*(p.lengthPar - 0.6*p.offset)
+ childStems = branches[min(3,n+1)]*(1.0 - 0.5*p.offset/p.lengthPar)
+ # If this is the last level before leaves then we need to generate the child points differently
+ else:
+ branchL = (length[n] + uniform(-lengthV[n],lengthV[n]))*(p.lengthPar - 0.6*p.offset)
+ if leaves < 0:
+ childStems = False
+ else:
+ childStems = leaves*shapeRatio(leafDist,p.offset/p.lengthPar)
+ # Determine the starting and ending radii of the stem using the tapering of the stem
+ startRad = min(p.radiusPar[0]*((branchL/p.lengthPar)**ratioPower), p.radiusPar[1])
+ endRad = startRad*(1 - taper[n])
newPoint.radius = startRad
- addstem(stemSpline(newSpline,curve[0]/curveRes[0],curveV[0]/curveRes[0],0,curveRes[0],branchL/curveRes[0],childStems,startRad,endRad,0))
- # If this isn't the trunk then we may have multiple stem to intialise
- else:
- # Store the old rotation to allow new stems to be rotated away from the previous one.
- oldRotate = 0
- # For each of the points defined in the list of stem starting points we need to grow a stem.
- for p in childP:
- # Add a spline and set the coordinate of the first point.
+ # If curveBack is used then the curviness of the stem is different for the first half
+ if curveBack[n] == 0:
+ curveVal = curve[n]/curveRes[n]
+ else:
+ curveVal = 2*curve[n]/curveRes[n]
+ # Add the new stem to list of stems to grow and define which bone it will be parented to
+ addstem(stemSpline(newSpline,curveVal,curveV[n]/curveRes[n],0,curveRes[n],branchL/curveRes[n],childStems,startRad,endRad,len(cu.splines)-1))
+ addsplinetobone(p.parBone)
+
+ childP = []
+ # Now grow each of the stems in the list of those to be extended
+ for st in stemList:
+ # When using pruning, we need to ensure that the random effects will be the same for each iteration to make sure the problem is linear.
+ randState = getstate()
+ startPrune = True
+ lengthTest = 0.0
+ # Store all the original values for the stem to make sure we have access after it has been modified by pruning
+ originalLength = st.segL
+ originalCurv = st.curv
+ originalCurvV = st.curvV
+ originalSeg = st.seg
+ originalHandleR = st.p.handle_right.copy()
+ originalHandleL = st.p.handle_left.copy()
+ originalCo = st.p.co.copy()
+ currentMax = 1.0
+ currentMin = 0.0
+ currentScale = 1.0
+ oldMax = 1.0
+ deleteSpline = False
+ orginalSplineToBone = copy.copy(splineToBone)
+ forceSprout = False
+ # Now do the iterative pruning, this uses a binary search and halts once the difference between upper and lower bounds of the search are less than 0.005
+ while startPrune and ((currentMax - currentMin) > 0.005):
+ setstate(randState)
+
+ # If the search will halt after this iteration, then set the adjustment of stem length to take into account the pruning ratio
+ if (currentMax - currentMin) < 0.01:
+ currentScale = (currentScale - 1)*pruneRatio + 1
+ startPrune = False
+ forceSprout = True
+ # Change the segment length of the stem by applying some scaling
+ st.segL = originalLength*currentScale
+ # To prevent millions of splines being created we delete any old ones and replace them with only their first points to begin the spline again
+ if deleteSpline:
+ for x in splineList:
+ cu.splines.remove(x.spline)
newSpline = cu.splines.new('BEZIER')
- cu.resolution_u = resU
newPoint = newSpline.bezier_points[-1]
- newPoint.co = p.co
- tempPos = zAxis.copy()
- # If the -ve flag for downAngle is used we need a special formula to find it
- if downAngleV[n] < 0.0:
- downV = downAngleV[n]*(1 - 2*shapeRatio(0,(p.lengthPar - p.offset)/(p.lengthPar - baseSize*scaleVal)))
- random()
- # Otherwise just find a random value
- else:
- downV = uniform(-downAngleV[n],downAngleV[n])
- downRotMat = Matrix.Rotation(downAngle[n]+downV,3,'X')
- tempPos.rotate(downRotMat)
- # If the -ve flag for rotate is used we need to find which side of the stem the last child point was and then grow in the opposite direction.
- if rotate[n] < 0.0:
- oldRotate = -copysign(rotate[n] + uniform(-rotateV[n],rotateV[n]),oldRotate)
- # Otherwise just generate a random number in the specified range
- else:
- oldRotate += rotate[n]+uniform(-rotateV[n],rotateV[n])
- # Rotate the direction of growth and set the new point coordinates
- rotMat = Matrix.Rotation(oldRotate,3,'Z')
- tempPos.rotate(rotMat)
- tempPos.rotate(p.quat)
- newPoint.handle_right = p.co + tempPos
- # If this is the first level of branching then upward attraction has no effect and a special formula is used to find branch length and the number of child stems
- if n == 1:
- vertAtt = 0.0
- lMax = length[1] + uniform(-lengthV[1],lengthV[1])
- branchL = p.lengthPar*lMax*shapeRatio(shape,(p.lengthPar - p.offset)/(p.lengthPar - baseSize*scaleVal))
- childStems = branches[2]*(0.2 + 0.8*(branchL/p.lengthPar)/lMax)
- elif storeN <= levels - 2:
- branchL = (length[n] + uniform(-lengthV[n],lengthV[n]))*(p.lengthPar - 0.6*p.offset)
- childStems = branches[min(3,n+1)]*(1.0 - 0.5*p.offset/p.lengthPar)
- # If this is the last level before leaves then we need to generate the child points differently
- else:
- branchL = (length[n] + uniform(-lengthV[n],lengthV[n]))*(p.lengthPar - 0.6*p.offset)
- if leaves < 0:
- childStems = False
+ newPoint.co = originalCo
+ newPoint.handle_right = originalHandleR
+ newPoint.handle_left = originalHandleL
+ (newPoint.handle_left_type,newPoint.handle_right_type) = ('VECTOR','VECTOR')
+ st.spline = newSpline
+ st.curv = originalCurv
+ st.curvV = originalCurvV
+ st.seg = originalSeg
+ st.p = newPoint
+ newPoint.radius = st.radS
+ splineToBone = orginalSplineToBone
+
+ # Initialise the spline list for those contained in the current level of branching
+ splineList = [st]
+ # For each of the segments of the stem which must be grown we have to add to each spline in splineList
+ for k in range(curveRes[n]):
+ # Make a copy of the current list to avoid continually adding to the list we're iterating over
+ tempList = splineList[:]
+ #print('Leng: ',len(tempList))
+ # For each of the splines in this list set the number of splits and then grow it
+ for spl in tempList:
+ if k == 0:
+ numSplit = 0
+ elif (k == 1) and (n == 0):
+ numSplit = baseSplits
else:
- childStems = leaves*shapeRatio(leafDist,p.offset/p.lengthPar)
- # Determine the starting and ending radii of the stem using the tapering of the stem
- startRad = min(p.radiusPar[0]*((branchL/p.lengthPar)**ratioPower), p.radiusPar[1])
- endRad = startRad*(1 - taper[n])
- newPoint.radius = startRad
- # If curveBack is used then the curviness of the stem is different for the first half
- if curveBack[n] == 0:
- curveVal = curve[n]/curveRes[n]
- else:
- curveVal = 2*curve[n]/curveRes[n]
- # Add the new stem to list of stems to grow and define which bone it will be parented to
- addstem(stemSpline(newSpline,curveVal,curveV[n]/curveRes[n],0,curveRes[n],branchL/curveRes[n],childStems,startRad,endRad,len(cu.splines)-1))
- addsplinetobone(p.parBone)
-
- childP = []
- # Now grow each of the stems in the list of those to be extended
- for st in stemList:
- # When using pruning, we need to ensure that the random effects will be the same for each iteration to make sure the problem is linear.
- randState = getstate()
- startPrune = True
- lengthTest = 0.0
- # Store all the original values for the stem to make sure we have access after it has been modified by pruning
- originalLength = st.segL
- originalCurv = st.curv
- originalCurvV = st.curvV
- originalSeg = st.seg
- originalHandleR = st.p.handle_right.copy()
- originalHandleL = st.p.handle_left.copy()
- originalCo = st.p.co.copy()
- currentMax = 1.0
- currentMin = 0.0
- currentScale = 1.0
- oldMax = 1.0
- deleteSpline = False
- orginalSplineToBone = copy.copy(splineToBone)
- forceSprout = False
- # Now do the iterative pruning, this uses a binary search and halts once the difference between upper and lower bounds of the search are less than 0.005
- while startPrune and ((currentMax - currentMin) > 0.005):
- setstate(randState)
-
- # If the search will halt after this iteration, then set the adjustment of stem length to take into account the pruning ratio
- if (currentMax - currentMin) < 0.01:
- currentScale = (currentScale - 1)*pruneRatio + 1
- startPrune = False
- forceSprout = True
- # Change the segment length of the stem by applying some scaling
- st.segL = originalLength*currentScale
- # To prevent millions of splines being created we delete any old ones and replace them with only their first points to begin the spline again
- if deleteSpline:
- for x in splineList:
- cu.splines.remove(x.spline)
- newSpline = cu.splines.new('BEZIER')
- newPoint = newSpline.bezier_points[-1]
- newPoint.co = originalCo
- newPoint.handle_right = originalHandleR
- newPoint.handle_left = originalHandleL
- (newPoint.handle_left_type,newPoint.handle_right_type) = ('VECTOR','VECTOR')
- st.spline = newSpline
- st.curv = originalCurv
- st.curvV = originalCurvV
- st.seg = originalSeg
- st.p = newPoint
- newPoint.radius = st.radS
- splineToBone = orginalSplineToBone
-
- # Initialise the spline list for those contained in the current level of branching
- splineList = [st]
- # For each of the segments of the stem which must be grown we have to add to each spline in splineList
- for k in range(curveRes[n]):
- # Make a copy of the current list to avoid continually adding to the list we're iterating over
- tempList = splineList[:]
- #print('Leng: ',len(tempList))
- # For each of the splines in this list set the number of splits and then grow it
- for spl in tempList:
- if k == 0:
- numSplit = 0
- elif (k == 1) and (n == 0):
- numSplit = baseSplits
- else:
- numSplit = splits(segSplits[n])
- if (k == int(curveRes[n]/2)) and (curveBack[n] != 0):
- spl.curvAdd(-2*curve[n]/curveRes[n] + 2*curveBack[n]/curveRes[n])
- growSpline(spl,numSplit,splitAngle[n],splitAngleV[n],splineList,vertAtt,handles,splineToBone)# Add proper refs for radius and attractUp
-
- # If pruning is enabled then we must to the check to see if the end of the spline is within the evelope
- if prune:
- # Check each endpoint to see if it is inside
- for s in splineList:
- coordMag = (s.spline.bezier_points[-1].co.xy).length
- ratio = (scaleVal - s.spline.bezier_points[-1].co.z)/(scaleVal*(1 - baseSize))
- # Don't think this if part is needed
- if (n == 0) and (s.spline.bezier_points[-1].co.z < baseSize*scaleVal):
- pass#insideBool = True
- else:
- insideBool = ((coordMag/scaleVal) < pruneWidth*shapeRatio(8,ratio,pruneWidthPeak,prunePowerHigh,prunePowerLow))
- # If the point is not inside then we adjust the scale and current search bounds
- if not insideBool:
- oldMax = currentMax
- currentMax = currentScale
- currentScale = 0.5*(currentMax + currentMin)
- break
- # If the scale is the original size and the point is inside then we need to make sure it won't be pruned or extended to the edge of the envelope
- if insideBool and (currentScale != 1):
- currentMin = currentScale
- currentMax = oldMax
+ numSplit = splits(segSplits[n])
+ if (k == int(curveRes[n]/2)) and (curveBack[n] != 0):
+ spl.curvAdd(-2*curve[n]/curveRes[n] + 2*curveBack[n]/curveRes[n])
+ growSpline(spl,numSplit,splitAngle[n],splitAngleV[n],splineList,vertAtt,handles,splineToBone)# Add proper refs for radius and attractUp
+
+ # If pruning is enabled then we must to the check to see if the end of the spline is within the evelope
+ if prune:
+ # Check each endpoint to see if it is inside
+ for s in splineList:
+ coordMag = (s.spline.bezier_points[-1].co.xy).length
+ ratio = (scaleVal - s.spline.bezier_points[-1].co.z)/(scaleVal*(1 - baseSize))
+ # Don't think this if part is needed
+ if (n == 0) and (s.spline.bezier_points[-1].co.z < baseSize*scaleVal):
+ pass#insideBool = True
+ else:
+ insideBool = ((coordMag/scaleVal) < pruneWidth*shapeRatio(8,ratio,pruneWidthPeak,prunePowerHigh,prunePowerLow))
+ # If the point is not inside then we adjust the scale and current search bounds
+ if not insideBool:
+ oldMax = currentMax
+ currentMax = currentScale
currentScale = 0.5*(currentMax + currentMin)
- if insideBool and ((currentMax - currentMin) == 1):
- currentMin = 1
- # If the search will halt on the next iteration then we need to make sure we sprout child points to grow the next splines or leaves
- if (((currentMax - currentMin) < 0.005) or not prune) or forceSprout:
- tVals = findChildPoints(splineList,st.children)
- # If leaves is -ve then we need to make sure the only point which sprouts is the end of the spline
- #if not st.children:
- if not st.children:
- tVals = [0.9]
- # If this is the trunk then we need to remove some of the points because of baseSize
- if n == 0:
- trimNum = int(baseSize*(len(tVals)+1))
- tVals = tVals[trimNum:]
-
- # For all the splines, we interpolate them and add the new points to the list of child points
- for s in splineList:
- #print(str(n)+'level: ',s.segMax*s.segL)
- childP.extend(interpStem(s,tVals,s.segMax*s.segL,s.radS))
-
- # Force the splines to be deleted
- deleteSpline = True
- # If pruning isn't enabled then make sure it doesn't loop
- if not prune:
- startPrune = False
-
- levelCount.append(len(cu.splines))
- # If we need to add leaves, we do it here
- if (storeN == levels-1) and leaves:
- oldRot = 0.0
- n = min(3,n+1)
- # For each of the child points we add leaves
- for cp in childP:
- # If the special flag is set then we need to add several leaves at the same location
- if leaves < 0:
- oldRot = -rotate[n]/2
- for g in range(abs(leaves)):
- (vertTemp,faceTemp,oldRot) = genLeafMesh(leafScale,leafScaleX,cp.co,cp.quat,len(leafVerts),downAngle[n],downAngleV[n],rotate[n],rotateV[n],oldRot,bend,leaves, leafShape)
- leafVerts.extend(vertTemp)
- leafFaces.extend(faceTemp)
- # Otherwise just add the leaves like splines.
- else:
+ break
+ # If the scale is the original size and the point is inside then we need to make sure it won't be pruned or extended to the edge of the envelope
+ if insideBool and (currentScale != 1):
+ currentMin = currentScale
+ currentMax = oldMax
+ currentScale = 0.5*(currentMax + currentMin)
+ if insideBool and ((currentMax - currentMin) == 1):
+ currentMin = 1
+ # If the search will halt on the next iteration then we need to make sure we sprout child points to grow the next splines or leaves
+ if (((currentMax - currentMin) < 0.005) or not prune) or forceSprout:
+ tVals = findChildPoints(splineList,st.children)
+ # If leaves is -ve then we need to make sure the only point which sprouts is the end of the spline
+ #if not st.children:
+ if not st.children:
+ tVals = [0.9]
+ # If this is the trunk then we need to remove some of the points because of baseSize
+ if n == 0:
+ trimNum = int(baseSize*(len(tVals)+1))
+ tVals = tVals[trimNum:]
+
+ # For all the splines, we interpolate them and add the new points to the list of child points
+ for s in splineList:
+ #print(str(n)+'level: ',s.segMax*s.segL)
+ childP.extend(interpStem(s,tVals,s.segMax*s.segL,s.radS))
+
+ # Force the splines to be deleted
+ deleteSpline = True
+ # If pruning isn't enabled then make sure it doesn't loop
+ if not prune:
+ startPrune = False
+
+ levelCount.append(len(cu.splines))
+ # If we need to add leaves, we do it here
+ if (storeN == levels-1) and leaves:
+ oldRot = 0.0
+ n = min(3,n+1)
+ # For each of the child points we add leaves
+ for cp in childP:
+ # If the special flag is set then we need to add several leaves at the same location
+ if leaves < 0:
+ oldRot = -rotate[n]/2
+ for g in range(abs(leaves)):
(vertTemp,faceTemp,oldRot) = genLeafMesh(leafScale,leafScaleX,cp.co,cp.quat,len(leafVerts),downAngle[n],downAngleV[n],rotate[n],rotateV[n],oldRot,bend,leaves, leafShape)
leafVerts.extend(vertTemp)
leafFaces.extend(faceTemp)
- # Create the leaf mesh and object, add geometry using from_pydata, edges are currently added by validating the mesh which isn't great
- leafMesh = bpy.data.meshes.new('leaves')
- leafObj = bpy.data.objects.new('leaves',leafMesh)
- bpy.context.scene.objects.link(leafObj)
- leafObj.parent = treeOb
- leafMesh.from_pydata(leafVerts,(),leafFaces)
- leafMesh.validate()
-
- if leafShape == 'rect':
- uv = leafMesh.uv_textures.new("leafUV")
- for tf in uv.data:
- tf.uv1, tf.uv2, tf.uv3, tf.uv4 = Vector((1, 0)), Vector((1, 1)), Vector((1 - leafScaleX, 1)), Vector((1 - leafScaleX, 0))
+ # Otherwise just add the leaves like splines.
+ else:
+ (vertTemp,faceTemp,oldRot) = genLeafMesh(leafScale,leafScaleX,cp.co,cp.quat,len(leafVerts),downAngle[n],downAngleV[n],rotate[n],rotateV[n],oldRot,bend,leaves, leafShape)
+ leafVerts.extend(vertTemp)
+ leafFaces.extend(faceTemp)
+ # Create the leaf mesh and object, add geometry using from_pydata, edges are currently added by validating the mesh which isn't great
+ leafMesh = bpy.data.meshes.new('leaves')
+ leafObj = bpy.data.objects.new('leaves',leafMesh)
+ bpy.context.scene.objects.link(leafObj)
+ leafObj.parent = treeOb
+ leafMesh.from_pydata(leafVerts,(),leafFaces)
+ leafMesh.validate()
+
+ if leafShape == 'rect':
+ uv = leafMesh.uv_textures.new("leafUV")
+ for tf in uv.data:
+ tf.uv1, tf.uv2, tf.uv3, tf.uv4 = Vector((1, 0)), Vector((1, 1)), Vector((1 - leafScaleX, 1)), Vector((1 - leafScaleX, 0))
# This can be used if we need particle leaves
# if (storeN == levels-1) and leaves:
@@ -793,136 +793,136 @@ def addTree(props):
# leafMesh.from_pydata(leafVerts,edgeList,())
# leafMesh.vertices.foreach_set('normal',normalList)
- # If we need and armature we add it
- if useArm:
- # Create the armature and objects
- arm = bpy.data.armatures.new('tree')
- armOb = bpy.data.objects.new('treeArm',arm)
- bpy.context.scene.objects.link(armOb)
-
- # Create a new action to store all animation
- newAction = bpy.data.actions.new(name='windAction')
- armOb.animation_data_create()
- armOb.animation_data.action = newAction
+ # If we need and armature we add it
+ if useArm:
+ # Create the armature and objects
+ arm = bpy.data.armatures.new('tree')
+ armOb = bpy.data.objects.new('treeArm',arm)
+ bpy.context.scene.objects.link(armOb)
+
+ # Create a new action to store all animation
+ newAction = bpy.data.actions.new(name='windAction')
+ armOb.animation_data_create()
+ armOb.animation_data.action = newAction
- arm.draw_type = 'STICK'
- arm.use_deform_delay = True
-
- # Add the armature modifier to the curve
- armMod = treeOb.modifiers.new('windSway','ARMATURE')
- #armMod.use_apply_on_spline = True
+ arm.draw_type = 'STICK'
+ arm.use_deform_delay = True
+
+ # Add the armature modifier to the curve
+ armMod = treeOb.modifiers.new('windSway','ARMATURE')
+ #armMod.use_apply_on_spline = True
+ armMod.object = armOb
+
+ # If there are leaves then they need a modifier
+ if leaves:
+ armMod = leafObj.modifiers.new('windSway','ARMATURE')
armMod.object = armOb
-
- # If there are leaves then they need a modifier
- if leaves:
- armMod = leafObj.modifiers.new('windSway','ARMATURE')
- armMod.object = armOb
-
- # Make sure all objects are deselected (may not be required?)
- for ob in bpy.data.objects:
- ob.select = False
- # Set the armature as active and go to edit mode to add bones
- bpy.context.scene.objects.active = armOb
- bpy.ops.object.mode_set(mode='EDIT')
-
- masterBones = []
-
- offsetVal = 0
+ # Make sure all objects are deselected (may not be required?)
+ for ob in bpy.data.objects:
+ ob.select = False
- # For all the splines in the curve we need to add bones at each bezier point
- for i,parBone in enumerate(splineToBone):
- s = cu.splines[i]
- b = None
- # Get some data about the spline like length and number of points
- numPoints = len(s.bezier_points)-1
- splineL = numPoints*((s.bezier_points[0].co-s.bezier_points[1].co).length)
- # Set the random phase difference of the animation
- bxOffset = uniform(0,2*pi)
- byOffset = uniform(0,2*pi)
- # Set the phase multiplier for the spline
- bMult = (s.bezier_points[0].radius/splineL)*(1/15)*(1/frameRate)
- # For all the points in the curve (less the last) add a bone and name it by the spline it will affect
- for n in range(numPoints):
- oldBone = b
- boneName = 'bone'+(str(i)).rjust(3,'0')+'.'+(str(n)).rjust(3,'0')
- b = arm.edit_bones.new(boneName)
- b.head = s.bezier_points[n].co
- b.tail = s.bezier_points[n+1].co
-
- b.head_radius = s.bezier_points[n].radius
- b.tail_radius = s.bezier_points[n+1].radius
- b.envelope_distance = 0.001#0.001
-
- # If there are leaves then we need a new vertex group so they will attach to the bone
- if (len(levelCount) > 1) and (i >= levelCount[-2]) and leafObj:
- leafObj.vertex_groups.new(boneName)
- elif (len(levelCount) == 1) and leafObj:
- leafObj.vertex_groups.new(boneName)
- # If this is first point of the spline then it must be parented to the level above it
- if n == 0:
- if parBone:
- b.parent = arm.edit_bones[parBone]
+ # Set the armature as active and go to edit mode to add bones
+ bpy.context.scene.objects.active = armOb
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ masterBones = []
+
+ offsetVal = 0
+
+ # For all the splines in the curve we need to add bones at each bezier point
+ for i,parBone in enumerate(splineToBone):
+ s = cu.splines[i]
+ b = None
+ # Get some data about the spline like length and number of points
+ numPoints = len(s.bezier_points)-1
+ splineL = numPoints*((s.bezier_points[0].co-s.bezier_points[1].co).length)
+ # Set the random phase difference of the animation
+ bxOffset = uniform(0,2*pi)
+ byOffset = uniform(0,2*pi)
+ # Set the phase multiplier for the spline
+ bMult = (s.bezier_points[0].radius/splineL)*(1/15)*(1/frameRate)
+ # For all the points in the curve (less the last) add a bone and name it by the spline it will affect
+ for n in range(numPoints):
+ oldBone = b
+ boneName = 'bone'+(str(i)).rjust(3,'0')+'.'+(str(n)).rjust(3,'0')
+ b = arm.edit_bones.new(boneName)
+ b.head = s.bezier_points[n].co
+ b.tail = s.bezier_points[n+1].co
+
+ b.head_radius = s.bezier_points[n].radius
+ b.tail_radius = s.bezier_points[n+1].radius
+ b.envelope_distance = 0.001#0.001
+
+ # If there are leaves then we need a new vertex group so they will attach to the bone
+ if (len(levelCount) > 1) and (i >= levelCount[-2]) and leafObj:
+ leafObj.vertex_groups.new(boneName)
+ elif (len(levelCount) == 1) and leafObj:
+ leafObj.vertex_groups.new(boneName)
+ # If this is first point of the spline then it must be parented to the level above it
+ if n == 0:
+ if parBone:
+ b.parent = arm.edit_bones[parBone]
# if len(parBone) > 11:
# b.use_connect = True
- # Otherwise, we need to attach it to the previous bone in the spline
- else:
- b.parent = oldBone
- b.use_connect = True
- # If there isn't a previous bone then it shouldn't be attached
- if not oldBone:
- b.use_connect = False
- #tempList.append(b)
+ # Otherwise, we need to attach it to the previous bone in the spline
+ else:
+ b.parent = oldBone
+ b.use_connect = True
+ # If there isn't a previous bone then it shouldn't be attached
+ if not oldBone:
+ b.use_connect = False
+ #tempList.append(b)
+
+ # Add the animation to the armature if required
+ if armAnim:
+ # Define all the required parameters of the wind sway by the dimension of the spline
+ a0 = 4*splineL*(1-n/(numPoints+1))/s.bezier_points[n].radius
+ a1 = (windSpeed/50)*a0
+ a2 = (windGust/50)*a0 + a1/2
+
+ # Add new fcurves for each sway as well as the modifiers
+ swayX = armOb.animation_data.action.fcurves.new('pose.bones["' + boneName + '"].rotation_euler',0)
+ swayY = armOb.animation_data.action.fcurves.new('pose.bones["' + boneName + '"].rotation_euler',2)
- # Add the animation to the armature if required
- if armAnim:
- # Define all the required parameters of the wind sway by the dimension of the spline
- a0 = 4*splineL*(1-n/(numPoints+1))/s.bezier_points[n].radius
- a1 = (windSpeed/50)*a0
- a2 = (windGust/50)*a0 + a1/2
-
- # Add new fcurves for each sway as well as the modifiers
- swayX = armOb.animation_data.action.fcurves.new('pose.bones["' + boneName + '"].rotation_euler',0)
- swayY = armOb.animation_data.action.fcurves.new('pose.bones["' + boneName + '"].rotation_euler',2)
-
- swayXMod1 = swayX.modifiers.new(type='FNGENERATOR')
- swayXMod2 = swayX.modifiers.new(type='FNGENERATOR')
-
- swayYMod1 = swayY.modifiers.new(type='FNGENERATOR')
- swayYMod2 = swayY.modifiers.new(type='FNGENERATOR')
-
- # Set the parameters for each modifier
- swayXMod1.amplitude = radians(a1)/numPoints
- swayXMod1.phase_offset = bxOffset
- swayXMod1.phase_multiplier = degrees(bMult)
-
- swayXMod2.amplitude = radians(a2)/numPoints
- swayXMod2.phase_offset = 0.7*bxOffset
- swayXMod2.phase_multiplier = 0.7*degrees(bMult) # This shouldn't have to be in degrees but it looks much better in animation
- swayXMod2.use_additive = True
-
- swayYMod1.amplitude = radians(a1)/numPoints
- swayYMod1.phase_offset = byOffset
- swayYMod1.phase_multiplier = degrees(bMult) # This shouldn't have to be in degrees but it looks much better in animation
-
- swayYMod2.amplitude = radians(a2)/numPoints
- swayYMod2.phase_offset = 0.7*byOffset
- swayYMod2.phase_multiplier = 0.7*degrees(bMult) # This shouldn't have to be in degrees but it looks much better in animation
- swayYMod2.use_additive = True
-
- # If there are leaves we need to assign vertices to their vertex groups
- if leaves:
- offsetVal = 0
- leafVertSize = 6
- if leafShape == 'rect':
- leafVertSize = 4
- for i,cp in enumerate(childP):
- for v in leafMesh.vertices[leafVertSize*i:(leafVertSize*i+leafVertSize)]:
- leafObj.vertex_groups[cp.parBone].add([v.index],1.0,'ADD')
-
- # Now we need the rotation mode to be 'XYZ' to ensure correct rotation
- bpy.ops.object.mode_set(mode='OBJECT')
- for p in armOb.pose.bones:
- p.rotation_mode = 'XYZ'
- treeOb.parent = armOb
- #print(time.time()-startTime)
+ swayXMod1 = swayX.modifiers.new(type='FNGENERATOR')
+ swayXMod2 = swayX.modifiers.new(type='FNGENERATOR')
+
+ swayYMod1 = swayY.modifiers.new(type='FNGENERATOR')
+ swayYMod2 = swayY.modifiers.new(type='FNGENERATOR')
+
+ # Set the parameters for each modifier
+ swayXMod1.amplitude = radians(a1)/numPoints
+ swayXMod1.phase_offset = bxOffset
+ swayXMod1.phase_multiplier = degrees(bMult)
+
+ swayXMod2.amplitude = radians(a2)/numPoints
+ swayXMod2.phase_offset = 0.7*bxOffset
+ swayXMod2.phase_multiplier = 0.7*degrees(bMult) # This shouldn't have to be in degrees but it looks much better in animation
+ swayXMod2.use_additive = True
+
+ swayYMod1.amplitude = radians(a1)/numPoints
+ swayYMod1.phase_offset = byOffset
+ swayYMod1.phase_multiplier = degrees(bMult) # This shouldn't have to be in degrees but it looks much better in animation
+
+ swayYMod2.amplitude = radians(a2)/numPoints
+ swayYMod2.phase_offset = 0.7*byOffset
+ swayYMod2.phase_multiplier = 0.7*degrees(bMult) # This shouldn't have to be in degrees but it looks much better in animation
+ swayYMod2.use_additive = True
+
+ # If there are leaves we need to assign vertices to their vertex groups
+ if leaves:
+ offsetVal = 0
+ leafVertSize = 6
+ if leafShape == 'rect':
+ leafVertSize = 4
+ for i,cp in enumerate(childP):
+ for v in leafMesh.vertices[leafVertSize*i:(leafVertSize*i+leafVertSize)]:
+ leafObj.vertex_groups[cp.parBone].add([v.index],1.0,'ADD')
+
+ # Now we need the rotation mode to be 'XYZ' to ensure correct rotation
+ bpy.ops.object.mode_set(mode='OBJECT')
+ for p in armOb.pose.bones:
+ p.rotation_mode = 'XYZ'
+ treeOb.parent = armOb
+ #print(time.time()-startTime)