原标题:【微笔记】houdini使用python创建城市教程笔记II
今天继续学习第二部分,使用python处理block和创建属性,批量处理导入的建筑模型。最大的感受是使用程序去处理批量重复的东西真TM的爽。比如导入100栋房子,然后都要链接一个bbox,分别创建三个属性和赋值,这种操作如果手动操作一遍也够累的,而且容易出错;万一遇到需要修改,那又得重头再来。而使用代码只需要修改一两个字符,按一个按钮完成~一个字:爽!
今天把第二部分的笔记1-8课 python基础介绍内容笔记整理分享出来,并且对每句代码都做了中文解释,对于重点语句加粗显示(看起来虽然很多,但是其实都是重复的东西)。在CG猎人vip群里的同学可以获得pdf版本,作为小福利吧。
09模块介绍
步骤预览
10city bloks城市分布基本处理
file载入模型→assamble对每一块进行分组命名为block_→transform 15倍到合适大小→手动选择中心面区域作为CBD商业中心,面组转化为点组→给个中心区域红色用来显示区分。
11-12city bock使用python创建属性
把前面的颜色节点去掉,在python节点中重新创建
新建python节点,一共要完成下面几个功能
#创建geometry上的属性(point属性 block_type和point_color)
#获取几何体上的点组
#查找CBD_group,设置颜色为红色,添加到list中
#设置街区类型属性
#create attribute
block_type = geo.addAttrib(hou.attribType.Point, "block_type", "") //创建点层级的空字符属性 block type
point_color =geo.addAttrib(hou.attribType.Point, "Cd", (0.0,0.0,0.0))//创建点层级颜色属性黑色
#fetch pointgroups on Geometry
point_groups=geo.pointGroups()//获得目前有的点组,返回一个列表
#find CBD_group, set color to red,and add to list
cbd_group= [] //定义一个列表,等下用于存储在对应组中的所有点
for group in point_groups://对所以组进行循环遍历
if group.name()=="CBD_group"://对组的名字进行判定
for point in group.points()://对组内的点进行遍历
point.setAttribValue("Cd",(1.0,0.0,0.0))//设置点的属性
cbd_group.append(point.number())//把点添加在之前创建的列表中
#set block type attribute
for point in geo.points()://对于所有点进行遍历
if point.number() in cbd_group://如果再cbd列表中的点
point.setAttribValue("block_type","commercial") 设置属性block type的值为commercial
elif point.number() not in cbd_group://对于不在cbd列表的点,设置block type值为houses
point.setAttribValue("block_type","houses")
else: //其他,直接pass掉
pass
13packing处理
添加pack节点,激活基于name名字属性来分pack处理,设置属性传递Cd,name和block_type
添加blast节点,可以基于block_type把模型区分开来
14存储点位置然后把点归中心
另外一边添加python节点,创建属性original_block_pos存储之前点的位置,然后把所有点位置归零
#create original block position attribute
original_block_pos = geo.addAttrib(hou.attribType.Point,"original_block_pos",(0.0,0.0,0.0))//为点创建属性original_block_pos,赋值为(0.0,0.0,0.0)
#set original block pos for each point and move to center
for point in geo.points(): //对每个点进行遍历
position=point.position()//把每个点的位置进行存储为position变量
point.setAttribValue("original_block_pos",position)//给之前定义original_block_pos进行赋值
center=(0.0,0.0,0.0)
point.setPosition(center)//设置现在每个点的位置0
14-20 对于建筑模型的处理
明确目标
1在building这个geo层级上创建python代码控制输入界面
2批量file导入硬盘中的建筑文件,这个建筑文件事先按照一定的命名规则
3创建boudingbox链接到file中
4创建attribute属性,需要分别创建三个属性 building_id,building_height和building_type,并且分别赋值
5创建switch和merge节点分别进行链接
1建筑模型命名规则(当你存储到硬盘的obj建筑缓冲模型的命名规则(非一致),便于后面python的批量调用。
所有建筑模型使用obj格式,代码会基于格式进行选择
house具名房子的命名规则为0001,0002.....4位数,然后以0为开头
commercial商业中心的房子分为三部分 基座,中间部分和顶部(如果没有这三部直接使用一个建筑也行)
命名规则为
1000,1001,1002
1010,1011,1012
其实这些都是一些作者定义的规律,你可以定义自己的规律,比如house01,house02,commercial01,commercial02等都行,只要有区分并且有明显方便选择的标志就好。
在obj物体层级上geo(改名为bulidings)使用之前类似与null创建执行python代码和按钮的方法创建控制参数。
添加folder作为标签管理,改名字为import buildings
添加file文件类型,作为导入文件的路径
添加seperator作为分解符
添加string设置为多行python代码
添加button用来执行string中的python代码
导入硬盘中的文件,我们需要通过命名规则进行筛选,也就要读取文件的文件格式,名字(首字母和末尾字母)这样我们需要导入操作系统中的库,面已经有预制好的方法等我们调用。
code中输入代码解释
最终节点区域结果
import os//导入os操作系统的模块,需要使用到对文件的处理
buildings_path = hou.node(".").parm("path").eval()//获取上面path定义的文件路径
buildings_folder=os.listdir(buildings_path//基于路径找到文件夹中的文件,返回列表
switch_houses=hou.node(".").createNode("switch","switch_houses")//在本geo中创建swith节点命名为switch_houses
switch_commercial = hou.node(".").createNode("switch","switch_commercial")//在本geo中创建swith节点命名为switch_commercial
merge=hou.node(".").createNode("merge")//在本geo中创建merge节点
counter =0 //创建一个计数器,在merge和swithc中会用到
for file in buildings_folder://遍历文件夹的文件
if file.endswith(".obj")://判定是否是obj文件
if file.startswith("0")://判定是否以0开头,这个是houses的建筑
#variables//定义变量
fullpath=buildings_path+file//获得文件的完整路径,也就是上面的路径+文件名
building_id =file.split(".")[0]//对文件名进行分割,以.为标准,左边为比如0000.obj分割为[0000,obj],第一格元素是0000,转化为数字就是0,以此类推0001就是1,0002就是2
#nodes
file_node=hou.node(".").createNode("file")//在geo层级中创建file节点
file_node.parm("file").set(fullpath)//设置file的路径为对应的文件名全路径
bbox=hou.node(".").createNode("bound")//创建一个bound节点
bbox.setFirstInput(file_node)//把这个节点链接到file节点中
attributes=hou.node(".").createNode("attribcreate")//创建一个attribute属性
attributes.parm("numattr").set(3)//设置这个attribute创建3个属性
attributes.parm("name1").set("building_id")//属性1的名字是building_id
attributes.parm("type1").set(1)//属性1的类型是整形
attributes.parm("value1v1").set(building_id)//设置id的值
attributes.parm("name2").set("building_height")//属性2的名字是building_height高度
attributes.parm("type2").set(0)//属性2的数据类型为浮点
attributes.parm("value2v1").setExpression('prim("../"+opinput(".",0),5,"P",1)')//设置表达式,获得最高点的高度
表达式的意义prim("../"+opinput(".",0),5,"P",1)嵌套了一个表达式 opinput(".",0)表示本节点输入第一个输入口的节点
prim获得是上一个节点bbox中第5个面(也就是顶面)的y轴的高度,也就是整个bbox的高度。
attributes.parm("name3").set("building_type")//设置属性3名字是building_type
attributes.parm("type3").set(3)//设置属性类型为字符
attributes.parm("string3").set("houses")//设置属性3的值为housese
#set inputs
attributes.setFirstInput(bbox)//设置属性的输入链接到bbox中
merge.setInput(counter,attributes)//设置merge节点,链接不同的物体,这时候counter每一次叠加一,分别从0,1,2这样表示接口
switch_houses.setInput(counter,attributes)//同理
counter+=1//每次叠加一
//后面对于commercial同理,只是判定条件从开头0修改为1,并且houses修改为commercial就行
if file.startswith("1"):
#variables
fullpath=buildings_path+file
building_id =file.split(".")[0]
#nodes
file_node=hou.node(".").createNode("file")
file_node.parm("file").set(fullpath)
bbox=hou.node(".").createNode("bound")
bbox.setFirstInput(file_node)
attributes=hou.node(".").createNode("attribcreate")
attributes.parm("numattr").set(3)
attributes.parm("name1").set("building_id")
attributes.parm("type1").set(1)
attributes.parm("value1v1").set(building_id)
attributes.parm("name2").set("building_hieght")
attributes.parm("type2").set(0)
attributes.parm("value2v1").setExpression('prim("../"+opinput(".",0),5,"P",1)')
attributes.parm("name3").set("building_type")
attributes.parm("type3").set(3)
attributes.parm("string3").set("commercial")
#set inputs
attributes.setFirstInput(bbox)
merge.setInput(counter,attributes)
switch_commercial.setInput(counter,attributes)
counter+=1
21总结
我们事先了对于截取地形的处理和对于建筑的分类处理
在第一部分街区处理中
我们使用了命名规范来packed物体
属性传递
使用python来创建和编辑属性
for循环使用
if条件语句
python列表
HOM houdini object model
第二部分批量导入建筑和模型
· 文件命名规律
参数界面边界器
使用os模块来把物体归入列表
使用python创建导入网络
使用python来设置hcript表达式
加入vipQ群的方法请戳下面文章返回搜狐,查看更多
责任编辑: