|
|
@@ -2,30 +2,29 @@
|
|
|
#scaleFactor = node.parm("scaleFactor").eval()
|
|
|
|
|
|
import random
|
|
|
-import os
|
|
|
-import sys
|
|
|
-from os import path
|
|
|
+import hou
|
|
|
+
|
|
|
+
|
|
|
|
|
|
node = hou.pwd()
|
|
|
geo = node.geometry()
|
|
|
|
|
|
-
|
|
|
# map user input
|
|
|
GENERATIONS = hou.ch('generations')
|
|
|
TROPISM = hou.Vector3(hou.parmTuple("tropDir").eval())
|
|
|
TROPISMFACTOR = hou.ch('tropStrength')
|
|
|
GRAVITYFACTOR = hou.ch('gFactor')
|
|
|
-SEED=123
|
|
|
+SEED = 1233
|
|
|
#hou.ch("falloff")
|
|
|
|
|
|
# the "seed"
|
|
|
# this is the first point from which the tree will grow.
|
|
|
-point=geo.createPoint()
|
|
|
-pointers=[point]
|
|
|
+point = geo.createPoint()
|
|
|
+pointers = [point]
|
|
|
|
|
|
# init the point attributes to store the values in, as these must exist.
|
|
|
# As we start, the first point's normal will point upward to grow in that direction.
|
|
|
-geo.addAttrib(hou.attribType.Point, "N", hou.Vector3([0,1,0]))
|
|
|
+geo.addAttrib(hou.attribType.Point, "N", hou.Vector3([0, 1, 0]))
|
|
|
geo.addAttrib(hou.attribType.Point, "Branch", 0)
|
|
|
geo.addAttrib(hou.attribType.Point, "Generation", 0)
|
|
|
geo.addAttrib(hou.attribType.Point, "BranchPoint", 0)
|
|
|
@@ -44,8 +43,8 @@ def duplicatePoint(p):
|
|
|
dupe.setPosition(p.position())
|
|
|
allAttr=geo.pointAttribs()
|
|
|
for i in allAttr:
|
|
|
- holder=None
|
|
|
- holder=p.attribValue(i)
|
|
|
+ holder = None
|
|
|
+ holder = p.attribValue(i)
|
|
|
dupe.setAttribValue(i, holder)
|
|
|
return dupe
|
|
|
|
|
|
@@ -54,128 +53,130 @@ def tropism(pt,vector,factor):
|
|
|
or a food source (roots)
|
|
|
'''
|
|
|
P = pt.position()
|
|
|
- vector=vector.normalized()
|
|
|
- pt.setPosition( P + (1*factor) * vector)
|
|
|
+ vector = vector.normalized()
|
|
|
+ pt.setPosition(P + (1*factor) * vector)
|
|
|
|
|
|
-def moveAlongNormal(pt,factor):
|
|
|
+def moveAlongNormal(pt, factor):
|
|
|
P = pt.position()
|
|
|
#P = hou.Vector3(P)
|
|
|
# be careful - this returns a value you cant simply add to P, must convert it to a hou.Vector3
|
|
|
N = pt.attribValue("N")
|
|
|
N = hou.Vector3(N)
|
|
|
- pt.setPosition( P + (1*factor) * N )
|
|
|
+ pt.setPosition(P + (1*factor) * N)
|
|
|
|
|
|
-def gravity(pt,factor):
|
|
|
+def gravity(pt, factor):
|
|
|
'''Convenience function to move down a point, multiplied by diameter.'''
|
|
|
P = pt.position()
|
|
|
# The downforce D
|
|
|
D = (1 - pt.attribValue('Diameter'))*factor
|
|
|
- G = hou.Vector3([0,D,0])
|
|
|
- pt.setPosition( P - G)
|
|
|
+ G = hou.Vector3([0, D, 0])
|
|
|
+ pt.setPosition(P - G)
|
|
|
|
|
|
|
|
|
def createRandomVector():
|
|
|
rx = (random.random()-0.5)*2
|
|
|
ry = (random.random()-0.5)*2
|
|
|
rz = (random.random()-0.5)*2
|
|
|
- return hou.Vector3([rx,ry,rz])
|
|
|
+ return hou.Vector3([rx, ry, rz])
|
|
|
|
|
|
-def addNoiseToNormal(pt,factor):
|
|
|
+def addNoiseToNormal(pt, factor):
|
|
|
N = pt.attribValue("N")
|
|
|
N = hou.Vector3(N)
|
|
|
rx = (random.random()-0.5)*2
|
|
|
ry = (random.random()-0.5)*2
|
|
|
rz = (random.random()-0.5)*2
|
|
|
- rvec = hou.Vector3([rx*factor,ry*factor,rz*factor])
|
|
|
+ rvec = hou.Vector3([rx*factor, ry*factor, rz*factor])
|
|
|
newN = rvec + 1 * N
|
|
|
pt.setAttribValue("N", newN)
|
|
|
return pt
|
|
|
|
|
|
-def rotateNormal(pt,factor,seed):
|
|
|
+
|
|
|
+def rotateNormal(pt, factor, seed):
|
|
|
N = pt.attribValue("N")
|
|
|
N = hou.Vector3(N)
|
|
|
|
|
|
- x = ( random.random()-0.5 )*2
|
|
|
- y = ( random.random()-0.5 )*2
|
|
|
- z = ( random.random()-0.5 )*2
|
|
|
- print 'p random x {0} y {1} z {2}'.format(x,y,z)
|
|
|
-
|
|
|
- x = ( hou.hmath.rand(seed+12*43)-0.5 )*2
|
|
|
- y = ( hou.hmath.rand(seed+2+2*3)-0.5 )*2
|
|
|
- z = ( hou.hmath.rand(seed+33*2)-0.5 )*2
|
|
|
- print 'h random x {0} y {1} z {2}'.format(x,y,z)
|
|
|
+ x = (random.random()-0.5)*2
|
|
|
+ y = (random.random()-0.5)*2
|
|
|
+ z = (random.random()-0.5)*2
|
|
|
+ print 'p random x {0} y {1} z {2}'.format(x, y, z)
|
|
|
+
|
|
|
+ x = (hou.hmath.rand(seed+12*43)-0.5)*2
|
|
|
+ y = (hou.hmath.rand(seed+2+2*3)-0.5)*2
|
|
|
+ z = (hou.hmath.rand(seed+33*2)-0.5)*2
|
|
|
+ print 'h random x {0} y {1} z {2}'.format(x, y, z)
|
|
|
|
|
|
- rvec = hou.Vector3([x*factor,y*factor,z*factor])
|
|
|
+ rvec = hou.Vector3([x*factor, y*factor, z*factor])
|
|
|
newN = rvec + 1 * N
|
|
|
pt.setAttribValue("N", newN)
|
|
|
return pt
|
|
|
|
|
|
-def getPointsByAttribValue(attr,val):
|
|
|
- plist=[]
|
|
|
+def getPointsByAttribValue(attr, val):
|
|
|
+ plist = []
|
|
|
for p in geo.iterPoints():
|
|
|
- if p.attribValue(attr)==val:
|
|
|
+ if p.attribValue(attr) == val:
|
|
|
plist.append(p)
|
|
|
return plist
|
|
|
|
|
|
-def getHighestNumericAttrVal(points,attr):
|
|
|
- val=0.0
|
|
|
+def getHighestNumericAttrVal(points, attr):
|
|
|
+ val = 0.0
|
|
|
for p in points:
|
|
|
- v=float(p.attribValue(attr))
|
|
|
- if v > val:val=v
|
|
|
+ v = float(p.attribValue(attr))
|
|
|
+ if v > val:
|
|
|
+ val = v
|
|
|
return val
|
|
|
|
|
|
|
|
|
|
|
|
-branchNum=0
|
|
|
+branchNum = 0
|
|
|
|
|
|
def step(pointers,stepseed):
|
|
|
''' step through all head pointers (aka growing branches)'''
|
|
|
updatedPointers=[]
|
|
|
for p in pointers:
|
|
|
#print 'pointer is point w/ # ' + str(p.number())
|
|
|
- newP=duplicatePoint(p)
|
|
|
+ newP = duplicatePoint(p)
|
|
|
#print 'copy is point w/ # ' + str(newP.number())
|
|
|
updatedPointers.append(newP)
|
|
|
- newP.setAttribValue('BranchPoint',newP.attribValue('BranchPoint')+1)
|
|
|
+ newP.setAttribValue('BranchPoint', newP.attribValue('BranchPoint')+1)
|
|
|
# Should we branch?
|
|
|
# TODO allow multiple branches at once
|
|
|
- rnd=random.random()
|
|
|
- rnd=hou.hmath.rand(stepseed+11)
|
|
|
+ rnd = random.random()
|
|
|
+ rnd = hou.hmath.rand(stepseed+11)
|
|
|
if rnd > 0.7:
|
|
|
# Dirty, find a better way soon!
|
|
|
global branchNum
|
|
|
- branchNum+=1
|
|
|
+ branchNum += 1
|
|
|
global treeInfo
|
|
|
#treeInfo['totalbranches']+=1
|
|
|
#print 'branch'
|
|
|
- branchP=duplicatePoint(p)
|
|
|
- branchP.setAttribValue('BranchPoint',0)
|
|
|
- b=branchP.attribValue('Branch')
|
|
|
- branchP.setAttribValue('Branch',branchNum)
|
|
|
+ branchP = duplicatePoint(p)
|
|
|
+ branchP.setAttribValue('BranchPoint', 0)
|
|
|
+ b = branchP.attribValue('Branch')
|
|
|
+ branchP.setAttribValue('Branch', branchNum)
|
|
|
#branchP.setAttribValue('Branch',b+1)
|
|
|
- g=branchP.attribValue('Generation')
|
|
|
- branchP.setAttribValue('Generation',g+1)
|
|
|
+ g = branchP.attribValue('Generation')
|
|
|
+ branchP.setAttribValue('Generation', g + 1)
|
|
|
updatedPointers.append(branchP)
|
|
|
- stepseed+=1
|
|
|
- newP=rotateNormal(newP,0.4,stepseed)
|
|
|
+ stepseed += 1
|
|
|
+ newP = rotateNormal(newP, 0.4, stepseed)
|
|
|
# now move along normal
|
|
|
- moveAlongNormal(newP,1)
|
|
|
- v=hou.Vector3(0,1,1)
|
|
|
- tropism(newP,TROPISM,TROPISMFACTOR)
|
|
|
- gravity(newP,GRAVITYFACTOR)
|
|
|
- newP.setAttribValue('Diameter',newP.attribValue('Diameter')*0.7 )
|
|
|
- stepseed+=1
|
|
|
- print 'seed ' + str(stepseed)
|
|
|
+ moveAlongNormal(newP, 1)
|
|
|
+ v = hou.Vector3(0, 1, 1)
|
|
|
+ tropism(newP, TROPISM, TROPISMFACTOR)
|
|
|
+ gravity(newP, GRAVITYFACTOR)
|
|
|
+ newP.setAttribValue('Diameter', newP.attribValue('Diameter')*0.7)
|
|
|
+ stepseed += 1
|
|
|
+ print 'seed', stepseed
|
|
|
return updatedPointers
|
|
|
|
|
|
|
|
|
-x=step(pointers,1)
|
|
|
+x = step(pointers, 1)
|
|
|
|
|
|
-seed=2
|
|
|
+seed = 2
|
|
|
for arsch in range(GENERATIONS):
|
|
|
#seed=1
|
|
|
- x = step(x,seed)
|
|
|
- seed+=1
|
|
|
+ x = step(x, seed)
|
|
|
+ seed += 1
|
|
|
|
|
|
|
|
|
|
|
|
@@ -183,7 +184,7 @@ for arsch in range(GENERATIONS):
|
|
|
|
|
|
|
|
|
def postprocess():
|
|
|
- tInfo={}
|
|
|
+ tInfo = {}
|
|
|
'''
|
|
|
for n in range(0,branchNum):
|
|
|
for p in geo.iterPoints():
|
|
|
@@ -193,32 +194,30 @@ def postprocess():
|
|
|
# print p.attribValue('BranchPoint')
|
|
|
'''
|
|
|
for p in geo.iterPoints():
|
|
|
- curBranch=p.attribValue('Branch')
|
|
|
- tInfo['branch']=curBranch
|
|
|
+ curBranch = p.attribValue('Branch')
|
|
|
+ tInfo['branch'] = curBranch
|
|
|
|
|
|
|
|
|
print '[[[[[[[[[[***]]]]]]]]]]'
|
|
|
-totalBranches=int(getHighestNumericAttrVal(geo.iterPoints(),'Branch'))
|
|
|
-#print geo.points()
|
|
|
+totalBranches = int(getHighestNumericAttrVal(geo.iterPoints(), 'Branch'))
|
|
|
|
|
|
for i in range(0,totalBranches):
|
|
|
# go through all branches
|
|
|
- max=0
|
|
|
+ max = 0
|
|
|
for p in getPointsByAttribValue('Branch',i):
|
|
|
- v=p.attribValue('BranchPoint')
|
|
|
- if v>max: max=v
|
|
|
+ v = p.attribValue('BranchPoint')
|
|
|
+ if v > max:
|
|
|
+ max = v
|
|
|
for p in getPointsByAttribValue('Branch',i):
|
|
|
- bp=p.attribValue('BranchPoint')
|
|
|
+ bp = p.attribValue('BranchPoint')
|
|
|
#print max
|
|
|
#print bp
|
|
|
try:
|
|
|
- relpos=float(bp)/float(max)
|
|
|
+ relpos = float(bp)/float(max)
|
|
|
except:
|
|
|
- relpos=0
|
|
|
+ relpos = 0
|
|
|
#p.setAttribValue('NormalizedPosition',1)
|
|
|
p.setAttribValue('NormalizedPosition', float(relpos))
|
|
|
- #print '---'
|
|
|
- #print bp + max
|
|
|
|
|
|
#print 'branch {0} points {1}'.format(i,max)
|
|
|
|