這篇記錄自己學習H過程中Py的部分腳本工具。
#來自呂老師的一個教程:
#需要注意的就是Houdini中設置父子關係的時候,如果要保留子級的原始的transform,在界面操作中要勾選Keep Position When Parenting,而在Py中操作時相當於保存transform,設置父子關係後在把transform復原回去
def createParentGeo(num):
geo = []
i = 0
while i < num:
geo.append(hou.node('/obj').createNode('geo'))
geo[i].parm('ty').set(3*i)
i+=1
j = 1
while j<num:
xform = geo[j].worldTransform()
geo[j].setFirstInput(geo[j-1])
geo[j].moveToGoodPosition()
geo[j].setWorldTransform(xform)
j+=1
def cancelParents():
selgeo = hou.selectedNodes()
i = 0
while i<len(selgeo):
xform = selgeo[i].worldTransform()
selgeo[i].setFirstInput(None)
selgeo[i].setWorldTransform(xform)
i+=1
#根據距離分組
#獲取當前的節點
node = hou.pwd()
#獲取到當前節點的幾何體(上級傳入的幾何體)
geo = node.geometry()
#創建一個距離組
pointGrp = geo.createPointGroup('dist_group')
#獲取Parameters
dist = hou.parm('distance').eval()
pos = hou.parmTuple('position').eval()
#功能部分
for point in geo.points():
length = hou.Vector3(point.position() - hou.Vector3(pos)).length()
if length < dist:
pointGrp.add(point)
# 在已知點的周圍撒點
# This code is called when instances of this SOP cook.
node = hou.pwd()
geo = node.geometry()
num = hou.parm('insertNum').eval()
range = hou.parm('range').eval()
seed = hou.parm('seed').eval()
delete = hou.parm('delOriginPoints').eval()
pos = []
for point in geo.points():
i = 0
while i < num:
rnd = hou.hmath.rand(point.number())#rand($PT)
xrand = point.position()[0] + (hou.hmath.rand(rnd+i+0.1+seed) - 0.5) * 2 * range
yrand = point.position()[1] + (hou.hmath.rand(rnd+i+2.6+seed) - 0.5) * 2 * range
zrand = point.position()[2] + (hou.hmath.rand(rnd+i+9.3+seed) - 0.5) * 2 * range
randPos = hou.Vector3(xrand, yrand, zrand)
pos.append(randPos)
i += 1
if delete == 1:
geo.clear()
j = 0
while j < len(pos):
p = geo.createPoint()
p.setPosition(pos[j])
j += 1
# 在每一個點組的平均位置上生成一個點
# This code is called when instances of this SOP cook.
node = hou.pwd()
geo = node.geometry()
positionList = []
numPointGroup = len(geo.pointGroups())
for currentGroup in geo.pointGroups():
xsum = ysum = zsum = 0
for currentPoint in currentGroup.points():
xsum += currentPoint.position()[0]
ysum += currentPoint.position()[1]
zsum += currentPoint.position()[2]
xaverage = xsum / len(currentGroup.points())
yaverage = ysum / len(currentGroup.points())
zaverage = zsum / len(currentGroup.points())
positionList.append((xaverage, yaverage, zaverage))
geo.clear()
for i in range(0, numPointGroup, 1):
point = geo.createPoint()
point.setPosition(positionList[i])
# 用點驅動模型運動,第一個輸入點是驅動的模型,第二個輸入點是動畫的點,第三個是動畫點的初始位置
# This code is called when instances of this SOP cook.
node = hou.pwd()
geo = node.geometry()
input2_geo = node.inputs()[1].geometry()
input3_geo = node.inputs()[2].geometry()
initPos = []
for input3point in input3_geo.points():
initPos.append(input3point.position())
tempPos = []
for input2Point in input2_geo.points():
tempPos.append(input2Point.position())
i = 0
for currentGroup in geo.pointGroups():
for currentPoint in currentGroup.points():
pos = tempPos[i] - initPos[i] + currentPoint.position()
pos = hou.Vector3(pos)
currentPoint.setPosition(pos)
i+=1
# This code is called when instances of this SOP cook.
# 把每一幀的屬性值累加起來,如果在時間軸上收到輸入幀數,此節點無效
node = hou.pwd()
geo = node.geometry()
attribName = node.parm('attribname').eval()
accumulateName = 'accumulated_' + attribName
points_tmp = geo.points()
#這裏的第三個參數是默認值,如果只寫0的話會被默認成整數,如果是浮點數要寫成0.0
geo.addAttrib(hou.attribType.Point, accumulateName, 0.0)
if hou.frame()==1:
accumulate = []
for i in range(0,len(points_tmp),1):
accumulate.append( points_tmp[i].attribValue(attribName))
points_tmp[i].setAttribValue(accumulateName,accumulate[i])
else:
for i in range(0, len(points_tmp), 1):
accumulate[i] += points_tmp[i].attribValue(attribName)
points_tmp[i].setAttribValue(accumulateName,accumulate[i])