Python —— 实用工具

12 篇文章 0 订阅

目录

工程起始节点配置

拆分所选节点的组

读取指定缓存路径下的若干缓存

根据节点左右位置排序

添加打开缓存目录的按钮

添加节点参数工具

删除节点参数工具

缓存每个Rop Geometry Output并渲染

写入写出数据 

将参数数据写入txt文本

将指定参数数据写入JSON

将指定参数的几何体属性数据写入JSON

将几何体所有属性数据导入JSON

从JSON导入几何体属性数据


工程起始节点配置

node = hou.node('/obj')

#列出所需创建的obj层级节点
names = ['null', 'Cam', 'CJ', 'Ani', 'Ref', 'FX']

#如已有所列的节点删除
nodes = []
for name in names:
    newnode = node.node(name)
    nodes.append(newnode)    
for newnode in nodes:
    if newnode:
        newnode.destroy()   

#创建obj层级的null节点,设置场景比例
null = node.createNode('null', 'null')
null.parm('scale').set(0.01)
null.setDisplayFlag(0)
pos = null.position()

idx = -4
for name in names:
    if name != 'null':
        if name == 'Cam':
            newnode = null.createOutputNode('alembicarchive', 'Cam')
            newnode.parm('fileName').set('$HIP/abc/$OS.abc')
            newnode.setDisplayFlag(0)
            newnode.setPosition([pos[0]+idx-2, pos[1]-2])
            
        elif name == 'FX':
            newnode = node.createNode('geo', name)
            newnode.setDisplayFlag(0)
            newnode.setPosition([pos[0], pos[1]-4])
            newnode.setColor(hou.Color((0.1,0.5,1)))
            
        else:
            newnode = null.createOutputNode('geo', name)
            newnode.setDisplayFlag(0)
            newnode.setPosition([pos[0]+idx, pos[1]-2])
            
            abc_node = newnode.createNode('alembic', name)
            abc_node.parm('fileName').set('$HIP/abc/$OS.abc')
            OUT_node = abc_node.createOutputNode('null', 'OUT_'+name)
            OUT_node.move([0,-2])
            
        idx += 4
                        
#在FX节点内导入外部CJ、Ani、Ref
geo_FX = hou.node('/obj/FX')
merge = geo_FX.createNode('merge')
merge_pos = merge.position()

OUT_node = merge.createOutputNode('null', 'Inputs')
OUT_node.move([0,-2])
OUT_node.setDisplayFlag(1)
OUT_node.setRenderFlag(1)

idx = -4
for name in names:
    if name != 'null' and name != 'Cam' and name != 'FX':
        obj_merge = geo_FX.createNode('object_merge')
        obj_merge.parm('objpath1').set('/obj/'+name+'/OUT_'+name)
        obj_merge.parm('xformtype').set(1)
        
        obj_merge.move([merge_pos[0]+idx, merge_pos[1]+2])
        merge.setNextInput(obj_merge)
        
        idx += 4

#创建用于渲染的节点
Render_node = node.node('Render_') 
if Render_node:
    Render_node.destroy()   
Render_node = node.createNode('geo', 'Render_')
Render_node.setPosition([pos.x(), pos.y()-6])
Render_node.setDisplayFlag(0)
Render_node.setColor(hou.Color((1,0,0)))

obj_merge = Render_node.createNode('object_merge')
obj_merge.parm('xformtype').set(1)
obj_merge.setRenderFlag(0)

OUT_node = Render_node.createNode('null', 'OUT')
OUT_node.move([0,-2])
OUT_node.setDisplayFlag(1)

#在obj层级创建材质渲染相关节点
cam_node = hou.node('/obj/Cam')
cam_pos = cam_node.position()

mat_node = node.node('matnet') 
if mat_node:
    mat_node.destroy()  
mat_node = node.createNode('matnet', 'matnet')
mat_node.setPosition([cam_pos[0], cam_pos[1]-2])
mat_node.createNode('principledshader::2.0')

rop_node = node.node('ropnet') 
if rop_node:
    rop_node.destroy()  
rop_node = node.createNode('ropnet', 'ropnet')
rop_node.setPosition([cam_pos[0], cam_pos[1]-3])
rop_node.createNode('ifd')

递归获取所有子节点(包括自身)

#递归获取所有子节点,包括自身
#等价于node.allSubChildren(),但此不包括自身
def allnodes(nodes, node):
    nodes.append(node.name())
    
    if(len(node.children()) != 0):
        for i in node.children():
            allnodes(nodes, i) 

拆分所选节点的组

import os

if(len(hou.selectedNodes()) == 0):
    hou.ui.displayMessage("未选择节点")
    
else:
    node = hou.selectedNodes()[0]
    geo = node.geometry()
    full_path = os.path.dirname(node.path())
    pos = node.position()
    groups = geo.primGroups()
    
    x = -3
    for group in groups:
        x += 3
        next_pos = [pos[0]+x, pos[1]-2]
        output_pos = [pos[0]+x, pos[1]-3]
        grpname = group.name()
        
        blast_node = hou.node(full_path).createNode("blast","blast_"+grpname)
        blast_node.setFirstInput(node)
        blast_node.setPosition(next_pos)        
       #blast_node.setParms({"group":grpname})
        blast_node.parm("group").set(grpname)
       #blast_node.setParms({"negate":1})
        blast_node.parm("negate").set(1)
        
        output_node = hou.node(full_path).createNode("null","OUT_"+grpname)
        output_node.setFirstInput(blast_node)
        output_node.setPosition(output_pos) 
        output_node.setColor(hou.Color(0.302,0.525,0.114))   

读取指定缓存路径下的若干缓存

import os

node = hou.selectedNodes()[0]
pos = node.position()
full_path = os.path.dirname(node.path())

files = os.listdir(node.parm("./basedir").eval())
merge_node = hou.node(full_path).createNode("merge","files")

x=0
for file in files:
   x += 3
   next_pos = [pos[0]+x, pos[1]]
   
   file_node = hou.node(full_path).createNode("file","file")
   file_node.setPosition(next_pos) 
   file_node.parm("file").set("$HIP/geo/"+node.name()+"/"+file+"/"+file+".$F4.bgeo.sc")
   
   merge_node.setNextInput(file_node)
  
merge_node.setPosition([pos[0]+3, pos[1]-4]) 

根据节点左右位置排序

import os

nodes = hou.selectedNodes()

if len(nodes) == 1:
    node = nodes[0]
    inputNodes = node.inputs()
    if len(inputNodes) > 1:
        inputNodes = sorted(inputNodes, key=lambda x : (x.position())[0])
    for i in range(len(inputNodes)):
        node.setInput(i, inputNodes[i])

添加打开缓存目录的按钮

//Callback Script
exec(hou.pwd().parm('code').eval())
import os

filepath = hou.pwd().parm('path').eval()

if os.path.exists(filepath) and os.path.isfile(filepath):
    dir = os.path.dirname(filepath)
    hou.ui.showInFileBrowser(dir)
    print(dir)
else:
    print("path wrong!")
import os

filepath = hou.pwd().parm('path').eval()

if os.path.exists(filepath) and os.path.isfile(filepath):
    splitpath = filepath.split('/')
    dir = "/".join(splitpath[0:-1])
    hou.ui.showInFileBrowser(dir)
    print(dir)
else:
    print("path wrong!")

添加节点参数工具

node = hou.selectedNodes()[0]

button_idx, values = hou.ui.readMultiInput(
    "Add Parms", ("Label", "name", "type", "size"),
    initial_contents=("Label", "newparameter", "float", "1"),
    title="Add Parms",
    buttons=("OK", "Cancel"),
    help="type: float or f, int or i, vetor or v, string or s"
)

if button_idx==0:
    if values[2] == 'float' or values[2] == 'f':
        parm = hou.FloatParmTemplate(values[1], values[0], int(values[3]))
        
    if values[2] == 'int' or values[2] == 'i':
        parm = hou.IntParmTemplate(values[1], values[0], int(values[3]))   
        
    if values[2] == 'vector' or values[2] == 'v':
        parm = hou.FloatParmTemplate(values[1], values[0], int(values[3]))
        
    if values[2] == 'string' or values[2] == 's':
        parm = hou.StringParmTemplate(values[1], values[0], int(values[3]))
        
    node.addSpareParmTuple(parm)

删除节点参数工具

node = hou.selectedNodes()[0]

button_idx, values = hou.ui.readMultiInput(
    "Del Parms", ("name",),
    initial_contents=("delparameter",),
    title="Del Parms",
    buttons=("Del parm", "Del All SpareParms", "Cancel"),
)

if button_idx==0:
    parm_tuple = node.parmTuple(values[0])
    parmTuples = node.parmTuples()

    if parm_tuple in parmTuples:               
        node.removeSpareParmTuple(parm_tuple)
            
if button_idx==1: 
    node.removeSpareParms()

缓存每个Rop Geometry Output并渲染

import os
nodes = hou.selectedNodes()

R_nodes = [];
#创建单独的用于渲染的节点
idx = 2
for node in nodes:
    #获取原始输出路径
    file = node.parm('sopoutput').unexpandedString()
    
    #创建obj层级的节点,如已存在先删除
    newnode = hou.node('/obj/'+'render_'+node.name())
    if newnode:
        newnode.destroy()
        
    pos = node.parent().position()
    newnode = hou.node('/obj').createNode('geo', 'render_'+node.name())
    newnode.setPosition([pos.x(), pos.y()-idx])
    newnode.setColor(hou.Color((1,0,0)))
    
    #在obj层级的节点内,创建加载缓存的节点
    newfilenode = newnode.createNode('file', node.name())
    #也可使用newnullnode = newfilenode.createOutputNode('null', 'display')
    newnullnode = newnode.createNode('null', 'display') 
    
    newnullnode.move([0, -2])
    newnullnode.setInput(0, newfilenode)
    
    newfilenode.parm('file').set(file)
    newfilenode.setRenderFlag(True)
    newnullnode.setDisplayFlag(True)
    
    #创建mantra渲染节点,如已存在先删除
    R_node = hou.node('/out/'+node.name())
    if R_node:
        R_node.destroy()
        
    R_node = hou.node('/out').createNode('ifd', node.name())
    R_node.move([0, -idx+2])
    R_node.parm('vobject').set('')
    R_node.parm('forceobject').set(newnode.name())
    R_node.parm('vm_picture').set('$HIP/render/$OS/$OS.$F4.exr')
    
    R_nodes.append(R_node)
    
    idx += 2

#缓存几何体
for node in nodes: 
    node.render() #等价于 node.parm('execute').pressButton()

#渲染
for node in R_nodes: 
    node.render() #等价于 node.parm('execute').pressButton()    
    

写入写出数据 

将参数数据写入txt文本
def fun(kwargs):
    node = kwargs['node']
    parm = node.parmTuple('s').eval()
    
    lines = str(parm)
    
    f = open('C:/test.txt', 'w')
    f.writelines(lines)
    f.close()
将指定参数数据写入JSON

def fun(kwargs):
    import json
    
    node = kwargs['node']
    parms = node.parmsInFolder(['myparms'])
    
    data = {}
    data['parms'] = []
    
    for parm in parms:
        name = parm.name()
        value = str(parm.eval())
        
        data['parms'].append({
            'name': name,
            'value': value
        })
    
    with open('c:/parms.json', 'w') as outfile:
        json.dump(data, outfile, indent=4)
将指定参数的几何体属性数据写入JSON

import json
nodes = hou.selectedNodes()
node = nodes[0]

path = node.parm('path').eval()
multiparm = node.parm('attribs')
instances = multiparm.multiParmInstances()
 
attrs = []
for attr in instances:
    attrs.append(attr.eval())

data = {
    'point': []
}

geo = node.geometry()
points = geo.points()

for point in points:
    id = point.number()
    pos = point.position()
    pos_arr = [pos[0], pos[1], pos[2]]
    
    point_data = {
        'id': id,
        'pos': pos_arr
    }

    for x in attrs:
        if geo.findPointAttrib(x) is not None:
            point_data[x] = point.attribValue(x)
            
    data['point'].append(point_data)
    
json_obj = json.dumps(data, indent=4, sort_keys=True)
with open(path, 'w') as outfile:
    outfile.write(json_obj)
将几何体所有属性数据导入JSON
import json
nodes = hou.selectedNodes()
node = nodes[0]
path = node.parm('path').eval()

data = {
    'point': []
}

geo = node.geometry()
points = geo.points()
attrbs = geo.pointAttribs()

for point in points:
    point_data = {}

    id = point.number()
    point_data['id'] = id

    for x in attrbs:
        point_data[x.name()] = point.attribValue(x.name())
            
    data['point'].append(point_data)
    
json_obj = json.dumps(data, indent=4, sort_keys=True)
with open(path, 'w') as outfile:
    outfile.write(json_obj)
从JSON导入几何体属性数据

import os
import json    

node = hou.pwd()
geo = node.geometry()

json_path = node.parm('path').evalAsString()

if len(json_path) > 0 and os.path.isfile(json_path):
    data = {}
    with open(json_path, 'r') as fp:
        data = json.load(fp)
    
    if len(data) > 0:
        for point in data['points']:
            pos = point['P']
            position = hou.Vector3(float(pos[0]), float(pos[1]), float(pos[2]))
            
            newpt = geo.createPoint()
            newpt.setPosition(position)
            
            for name, value in point.items():            
                if name != 'P' and name != 'id':                   
                    if geo.findPointAttrib(name) == None:
                            attrib = geo.addAttrib(hou.attribType.Point, name, value)          
                    newpt.setAttribValue(name, value)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值