diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-11-19 20:19:08 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-11-19 20:19:08 +0400 |
commit | 9ac0a714bee5df2153e0a73bb55962139ba18eb2 (patch) | |
tree | 029104d14b7e942dd616bf8443e09d0461ac6350 /add_curve_sapling/utils.py | |
parent | 5e44117da5a35882e7f3919f4c48c234acebe045 (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/utils.py')
-rw-r--r-- | add_curve_sapling/utils.py | 944 |
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) |