// кастомный криптомат из атрибута (points, primitive) s@`chs("name_crypto")` = sprintf('`chs("name_crypto")`%d', @`chs("attrib_name")`+chi("number")); // нойз в вексе (points) float noise = fit(snoise(@P * chf('scale'), chi('turbulence'), chf('rough'), chf('attenuation')), chf('min_noise'), chf('max_noise'), 0, 1); @Cd=noise; // выравнивание по двум точкам и оси (point) int pt1 = chi('pt_num1'); int pt2 = chi('pt_num2'); vector v_pts = point(0, 'P', pt2) - point(0, 'P', pt1); vector axis = {0, 0, 1}; @orient = dihedral(axis, v_pts); // выравнивание через функцию intersect (points) // input 0 - geo to, input 1 - geo from vector hitdir = {0,10000,0}; vector uvw, hitPoint_high, hitPoint_low; int prims_low = intersect(1, @P, hitdir, hitPoint_high, uvw); int prims_high = intersect(1, @P, -hitdir, hitPoint_low, uvw); if (prims_high >=0) @P = hitPoint_low; if (prims_low >=0) @P = hitPoint_high; // выравнивание по uv (points) // input 0 - geo to, input 1 - geo from int prim; vector uv; xyzdist(1, @P, prim, uv); @P = primuv(1, 'P', prim, uv); // нахождение минимального и максимального значения в атрибуте (points) float values[]; float value; int array_value = @numpt; for (int i=0; i<array_value; i++) { value = point(geoself(), 'P', i); append(values, value); } @min_value = min(values); @max_value = max(values); // создание целочисленного атрибута из всех групп объекта (points) string groups[] = detailintrinsic(0, 'pointgroups'); int x = 0; foreach(string i; groups) { if(inpointgroup(0, i, @ptnum)==1) i@id_groups = x; x++; } // дистанция от камеры на геометрии (points) matrix camxform = optransform(chs('camera_path')); vector pos_cam = set(0,0,0) * camxform; vector pos_ground = point(0, 'P', @ptnum); float far = chf('far'); float d = distance(pos_cam, pos_ground); if (d<far) @mask_obj = 1; @mask_dist = chramp('ramp_distance', fit(d, 0, far, 1, 0)); @Cd = @mask_dist; // забрать world трансформацию с объекта на obj уровне (detail) string path = chs('path_node'); matrix m = optransform(opfullpath(path)); vector null_pos = set(m.ax, m.ay, m.az); v@pos = set(m.ax, m.ay, m.az); v@scale = cracktransform(0, 0, 2, @P, m); v@rot = cracktransform(0, 0, 1, @P, m); @orient = quaternion(matrix3(m)); addpoint(geoself(), null_pos); // добавить эту трансформацию на точки (points) v@pos = detailattrib(0, 'pos', 0, 1); @orient = detailattrib(0, 'orient', 0, 1); @scale = detailattrib(0, 'scale', 0, 1); // создать группу по path атрибуту (glob) (primitive) if (s@path ~= '*name*') setprimgroup(0, 'gr_name', @primnum, 1); // случайные цвета точек по рампе (points) int type_attrib = @ptnum; float rnd_value = fit01(rand(type_attrib + chf('seed')), 0, 1) * 2; vector ramp = chramp('ramp_color', rnd_value); @Cd=ramp; // случайные значения масштаба и поворота на точках (points) float angle; vector axis; //random scale @pscale=fit01(rand(@ptnum) * rand(ch('seed') * @ptnum), ch('min_scale'), ch('max_scale')); //random rotation axis = {0,1,0}; angle = fit((rand(@ptnum)) * chf('rotation'), 0, 1, 0, 10); @orient = quaternion(angle, axis); // собрал здесь функции для работы со строковыми атрибутами s[]@path_split = split(s@path, '/'); // разбить массив символом resize(s[]@path_split, 1); // изменить размер массива push(s[]@path_split, 'preview'); // добавить объект в массив i@len_path = len(s[]@pathSplit); // вычислить длину массива s@name_attrib = pop(s[]@pathSplit, 1); // забрать строку из массива s@name_join = join(s[]@pathSplit, '.'); // объединить массив символом в строку s[]@slice = slice(s[]@test, 1, 5); // разрезать строку, начало строки/конец строки i@nums = opdigits(string); // найти последние цифры в строке f@nums = atof(re_replace(r'[^.0-9]+', '', s@path)); // вернуть цифры из строки i@num = re_match ('word', s@path) // вернуть 1 если слово в строке
# arnold # открыть параметр shdowmask на arnold light (по умолчанию он скрыт) sel = hou.selectedNodes() for light in sel: null_tg = light.parmTemplateGroup() copy_parm_template = null_tg.find("shadowmask") null_tg.hide(copy_parm_template, False) light.setParmTemplateGroup(null_tg) # arnold # добавить фильтр light decay на arnold light с вынесенным параметром far decay в папку Light import re sel = hou.selectedNodes() for light in sel: g = light.parmTemplateGroup() folder = g.findFolder(' Light ') t = hou.ToggleParmTemplate('decay_far', 'decay far') p = hou.FloatParmTemplate("decay", "decay light", 1, default_value=[10]) g.appendToFolder(folder, t) g.appendToFolder(' Light ', p) light.setParmTemplateGroup(g) light.allowEditingOfContents() childs = light.allSubChildren() for shader in childs: match = re.search('arnold_vopnet', str(shader)) if match: path_shader = shader.path() path_out = path_shader + '/OUT_light' out = hou.node(path_out) decay=shader.createNode('arnold::light_decay') decay.moveToGoodPosition() decay.parm('use_far_atten').setExpression('ch("../../../decay_far")') decay.parm('far_end').setExpression('ch("../../../decay")') out.setInput(2, decay) # arnold # скрипт создает референсную ноду arnold triplanar в материале select_node = hou.selectedNodes()[0] select_node_name = select_node.name() network_path = '/'.join(select_node.path().split('/')[:-1]) network = hou.node(network_path) sel_pos = select_node.position() triplanar=network.createNode('arnold::triplanar') triplanar.setPosition(sel_pos) triplanar.move([0, -2]) script = 'ch("../' + select_node_name triplanar.parm('scalex').setExpression(script+'/scalex")') triplanar.parm('scaley').setExpression(script+'/scaley")') triplanar.parm('scalez').setExpression(script+'/scalez")') triplanar.parm('rotatex').setExpression(script+'/rotatex")') triplanar.parm('rotatey').setExpression(script+'/rotatey")') triplanar.parm('rotatez').setExpression(script+'/rotatez")') triplanar.parm('offsetx').setExpression(script+'/offsetx")') triplanar.parm('offsety').setExpression(script+'/offsety")') triplanar.parm('offsetz').setExpression(script+'/offsetz")') triplanar.parm('coord_space').setExpression('chs("../'+ select_node_name +'/coord_space")') triplanar.parm('blend').setExpression(script+'/blend")') triplanar.parm('cell').setExpression(script+'/cell")') triplanar.parm('cell_rotate').setExpression(script+'/cell_rotate")') triplanar.parm('cell_blend').setExpression(script+'/cell_blend")') # arnold # скрипт создает arnold light по позициям точек (также при наличии добавляет атрибут 'rotation') import re root = hou.node('/obj/') name_light = 'name_light' path_pt = '/obj/sphere1/OUT' pt_node = hou.node(path_pt) pts = pt_node.geometry().points() list_num=[] for pt in pts: list_num.append(pt) nums=str(len(list_num)-1) nums_int=int(nums) ar_light=root.createNode('arnold_light') ar_light.setName(name_light, unique_name=True) ar_light.move([0, -nums_int]) attribs_pt = pt_node.geometry().pointAttribs() match_rotation = re.search("rotation", str(attribs_pt)) position_exp0 ='point("' + path_pt + '", '+ nums +', "P", 0)' position_exp1 ='point("' + path_pt + '", '+ nums +', "P", 1)' position_exp2 ='point("' + path_pt + '", '+ nums +', "P", 2)' rotation_exp0 ='point("' + path_pt + '", '+ nums +', "rotation", 0)' rotation_exp1 ='point("' + path_pt + '", '+ nums +', "rotation", 1)' rotation_exp2 ='point("' + path_pt + '", '+ nums +', "rotation", 2)' ar_light.parm('tx').setExpression(position_exp0) ar_light.parm('ty').setExpression(position_exp1) ar_light.parm('tz').setExpression(position_exp2) if match_rotation: ar_light.parm('rx').setExpression(rotation_exp0) ar_light.parm('ry').setExpression(rotation_exp1) ar_light.parm('rz').setExpression(rotation_exp2) # добавить параметр lightmask на ноду instance (по умолчанию его нет) sel = hou.selectedNodes() for node_instance in sel: group = node_instance.parmTemplateGroup() folder = group.findFolder('Render') lm=hou.StringParmTemplate('lightmask', 'Light Mask', 1, default_value=('*',)) lm.setStringType(hou.stringParmType.NodeReferenceList) tags = lm.tags() tags["opexpand"] = '1' tags["spare_category"] = 'Shading' tags["opfilter"] = '!!OBJ/LIGHT!!' tags["oprelative"] = '/obj' lm.setTags(tags) group.appendToFolder(folder, lm) node_instance.setParmTemplateGroup(group) # перезагрузить текущую сцену hip_path = str(hou.getenv("HIPFILE")) # get current path scene hou.hipFile.save() # save scene hou.hipFile.clear(suppress_save_prompt=True) # clear scene hou.hipFile.load(hip_path) #load scene # аналог save selected, скрипт сохраняет выделенные ноды по указанному пути import hou, re path_to_save = '/home/users/your_name/Documents/test.hip' #attribs hip_path = str(hou.getenv("HIPFILE")) sel=hou.selectedNodes() obj = hou.node('/obj/') mat = hou.node('/mat/') out = hou.node('/out/') shop = hou.node('/shop/') path_to_load = '' hou.hipFile.save() #save scene hou.copyNodesToClipboard(sel) #copy to clipboard select nodes # find network for nodes in sel: match_obj = re.search('/obj/', str(nodes.path())) match_mat = re.search('/mat/', str(nodes.path())) match_out = re.search('/out/', str(nodes.path())) #match_matnet = re.search('matnet', str(nodes.path())) shopnet_name = nodes.path().split('/')[-2] match_shopnet = re.search('shop', str(shopnet_name)) matnet_name = nodes.path().split('/')[-2] match_matnet = re.search('matnet', str(matnet_name)) if match_obj: path_to_load = obj if match_mat: path_to_load = mat if match_out: path_to_load = out if match_matnet: path_to_load = mat if match_shopnet: path_to_load = shop hou.hipFile.clear(suppress_save_prompt=True) # clear scene hou.pasteNodesFromClipboard(path_to_load) # paste nodes from clipboard hou.hipFile.save(path_to_save) # save scene hou.hipFile.load(hip_path) # load current scene # запустить программу через terminal import os path = '/home/users/name/local_arnold/5.6.0/18.5.462/scripts/bin/kick -info polymesh' #linux path = "\"C:/ProgramData/Autodesk/ApplicationPlugins/MAXtoA_2021/kick -info polymesh\"" #windows os.system(path) # скрипт создает rivets из точек с группами import re obj=hou.node('/obj') name_set = 'pt_name' path = '/obj/sphere1/OUT' pt_node = hou.node(path) pts = pt_node.geometry().points() groups = pt_node.geometry().pointGroups() n_groups = len(groups) if n_groups == 1: groups_names = str(groups).split(' ')[1] list_num=[] for pt in pts: list_num.append(pt) iterator=len(list_num) nums = str(iterator-1) attribs_pt = pt_node.geometry().pointAttribs() match_N = re.search("(\'N\')", str(attribs_pt)) match_up = re.search("(\'up\')", str(attribs_pt)) if n_groups != 1: groups_arr = groups[iterator-1] groups_names = str(groups_arr).split(' ')[1] rivet=obj.createNode('rivet') rivet.setName('rivet_'+name_set+nums, unique_name=True) rivet.move([0, -1 - int(nums)]) rivet.parm('rivetsop').set(path) rivet.parm('rivetgroup').set(groups_names) if match_N and match_up: rivet.parm('rivetuseattribs').set('1') # скрипт есть смысл использовать если к вам пришла геометрия с лейаута, а вам надо вывести ее содержимое в отдельные ноды и зашейдить # скрипт находит в выделенных нодах все ноды с рендер флагами и на obj уровне создает geo ноду с object merge в которой указан путь на ноду с рендер флагом. root = hou.node('/obj/') sel = hou.selectedNodes() if sel != (): for nodes in sel: name_node=nodes.name() name_node = 'shots_' + name_node sub_nodes = nodes.allSubChildren(recurse_in_locked_nodes=False) for child_nodes in sub_nodes: flag_node = child_nodes.isGenericFlagSet(hou.nodeFlag.Render) if flag_node == True: geo_path=child_nodes.path() geo = root.createNode('geo') geo.setName(name_node, unique_name=True) geo.moveToGoodPosition() obj_merge=geo.createNode('object_merge') obj_merge.parm('objpath1').set(geo_path) obj_merge.parm('xformtype').set('local') # вынес сюда некоторые часто используемые функции # операции с нодами main = hou.pwd() # вернуть ноду содержащую параметр new_node = main.createNode('node_name') # создать ноду new_node.destroy() # удалить ноду main_childs = main.children() # вернуть ноды с нижнего уровня текущей ноды main_sub_childs = main.allSubChildren() # вернуть все ноды ниже текущей new_name = main.setName('name', unique_name=True) # изменить имя ноды # внешний вид нод red = hou.Color((1.0, 0, 0)) # добавить цвет main.setColor(red) # назначить цвет на ноду main_pos = main.position() # вернуть позицию ноды new_node.move([0, -1]) # переместить ноду new_node.setPosition(main_pos) # переместить в позицию другой ноды new_node.isGenericFlagSet(hou.nodeFlag.Display) # вернуть флаг new_node.setGenericFlag(hou.nodeFlag.Display, 1) # установить флаг в положении видимый (1) или невидимый (0) # операции с параметрами parm_path = node.parm('parm_name').path() # вернуть путь до параметра node.parm('parm_name').set('/obj/') # изменить параметр node.parm('parm_name').setExpression('expression') # добавить экспрешн в параметр node.parm("parm_name").set(ref_node.parm("parm_name")) # установить ссылку на параметр parm_value = node.evalParm('update_paths') # вернуть значение параметра node.parm('parm_name').pressButton() # нажать на кнопку # связи node_from.setInput(0, node_to, 1) # соединить ноды по номеру каналов node_from.setNamedInput('normal', node_to, 'vector') # соединить ноды по названию каналов node_from.setNextInput(node_to, output_index=0) # соединить ноду к следующему входу (например нода merge) nodes_from.outputs() # вернуть все выходы nodes_from.inputs() # вернуть все входы # строковые функции num_to_text = str(100) # сконвертировать в строковую переменную path_split = text.split('/') # разбить в лист по символу path_join = '/'.join(list) # объединить лист в строку по символу rename = re.sub('png', 'tx', path) # regex, изменить текст в строке: png - исходный текст, tx - исправленый, path - строка match = re.search('text', path) # regex, найти текст в строке slice = str[0:10] # разрезать строку: 0 - начало строки, 10 - длина строки