def _paste(self): """ Basic Pasting method. """ hou.hscript("source " + self._copyFile)
def main(): """Main function.""" # Initialize color settings. ht.nodes.colors.createSessionColorManager() # Remove an icon cache directory variable if it exists. hou.hscript("set -u HOUDINI_ICON_CACHE_DIR")
def pbStartUp(): startup_nodes = {'cam': 'RenderCam', 'ropnet': 'ROP', 'shopnet': 'SHOP', 'cop2net': 'COP', 'geo': '_FX', 'geo': 'RENDER_', } # startup with some obj node types by default # for op in range(len(startup_nodes)): nodetype = startup_nodes.keys()[op] objnode = hou.node('/obj').createNode(nodetype, startup_nodes[nodetype]) objnode.setPosition(hou.Vector2((6-op*2, 5))) # create mantra on startup and set camera to RenderCam mantra = hou.node('/obj/ROP').createNode('ifd', 'test_render') mantra.parm('camera').set('../../RenderCam') # create delayed load on stratup hou.node('/obj/SHOP').createNode('vm_geo_file', 'delayed_load_') # prepare render geo render = hou.node('/obj/RENDER_') for child in render.children(): child.destroy() render.createNode('null', 'NOTHING') render.parm('shop_geometrypath').set('../SHOP/delayed_load_') # load 123.cmd hou.hscript('$HFS/houdini/scripts/123.cmd')
def setParent(self, parent): ''' Set the current take's parent, it can be either a Take object, a take name or None. If None, the take's parent will be set to Main take. ''' if parent is None: result = hou.hscript("takemove {0} Main".format(self.getName())) if result[1]: raise TakeError(result[1]) self.parent = "Main" self._parent = "-p Main" else: if isinstance(parent, Take): parent = parent.getName() if not parent in _listTakeNames(): raise TakeError("Take {0} not found in take list.".format(parent)) result = hou.hscript("takemove {0} {1}".format(self.getName(), parent)) if result[1]: raise TakeError(result[1]) self.parent = parent self._parent = "-p " + parent
def set_frame_range(self, start_frame=1, end_frame=100, adjust_frame_range=False): """sets the frame range """ # -------------------------------------------- # set the timeline current_frame = hou.frame() if current_frame < start_frame: hou.setFrame(start_frame) elif current_frame > end_frame: hou.setFrame(end_frame) # for now use hscript, the python version is not implemented yet hou.hscript( 'tset `(' + str(start_frame) + '-1)/$FPS` `' + str( end_frame) + '/$FPS`' ) # -------------------------------------------- # Set the render nodes frame ranges if any # get the out nodes output_nodes = self.get_output_nodes() for output_node in output_nodes: output_node.setParms( {'trange': 0, 'f1': start_frame, 'f2': end_frame, 'f3': 1} )
def disableAttributeVisualization(view_path, option_name): """ Disable a display option in a specific viewer. view_path: Path to the viewport. option_name: Name of the the display option to disable. """ hou.hscript("viewoptenable %s all -%s" % (view_path, option_name))
def set_namespace_aliases(prefix="qLib::", alias=True, verbose=False): """ Defines (non-)namespaced aliases for operators with a particular namespace prefix. This is used for always creating the namespaced versions of assets, even if an older .hip file contains non-namespaced asset names. Mapping looks like: <opname> --> <prefix>::<opname>::<version> @note IMPORTANT: Although the manual says it's fine to omit the version of a namespaced asset (and that would refer to the latest version), omitting it results in files getting messed up when loaded, so version numbers _are_ included in the opaliases. @note This function should be called (preferably) on Houdini startup, e.g. import qlibutils qlibutils.set_namespace_aliases( ["qLib::", "myStuff::"] ) @todo For each asset, the highest version number should be found and used. Right now it uses the first version it founds (which is fine for now). """ if type(prefix) is list: for p in prefix: set_namespace_aliases(p) return assert "::" in prefix, "Include trailing '::' characters in prefix" cmds = [] for file in hou.hda.loadedFiles(): names = [ (d.nodeType().name(), d.nodeTypeCategory().name()) \ for d in list(hou.hda.definitionsInFile(file)) \ if prefix in d.nodeType().name() ] for n in names: try: # strip namespace prefix and version suffix old = re.sub("^[^:]+::", "", n[0]) old = re.search("^[^:]+", old).group(0) # opalias <network> <namespaced-op.> <plain-old-op.> cmd = "opalias %s %s %s" % (n[1], n[0], old) if cmd not in cmds: if verbose: print cmd if alias: hou.hscript(cmd) cmds.append(cmd) else: print "# ALREADY ALIASED: %s (%s)" % (cmd, file) except: print "ERROR: %s" % traceback.format_exc()
def setJob(job_dir = None): if not job_dir: select_dir = hou.ui.selectFile(file_type = hou.fileType.Directory) if not select_dir: return False job_dir = select_dir[:-1] hou.hscript("job %s" % job_dir) return True
def __init__(self, name="pytake", parent="", set_to_current=False, include_node=None, include_parm=None, _add_to_scene=True): if not hasattr(include_parm, "__iter__"): if include_parm is None: include_parm = [] else: include_parm = [include_parm] if not hasattr(include_node, "__iter__"): if include_node is None: include_node = [] else: include_node = [include_node] self.set_to_current = set_to_current self.take_members = {} # Construc take's name if _add_to_scene: self.name = _incName(_checkName(name)) else: self.name = _checkName(name) # Construct parent string if not parent: if hou.expandString('$ACTIVETAKE') != "Main": parent = hou.expandString('$ACTIVETAKE') else: if isinstance(parent, Take): parent = parent.getName() if parent: self._parent = "-p " + parent self.parent = parent else: self._parent = "" self.parent = parent # Create Take and add it to the list of takes if _add_to_scene: self._createTake() # if node or parms included add it if include_parm: self.includeParms(include_parm) if include_node: for n in include_node: self.includeParmsFromNode(n) # set current if _add_to_scene: if self.set_to_current: hou.hscript("takeset " + self.name) else: hou.hscript("takeset Main")
def copy(self): """ Read the selected nodes and do checks to see if there is anything we want to flag to the user. then pass the data to the write function. """ lockedAssets = False # Get selected nodes and check if it's a locked asset. for node in hou.selectedNodes(): if self.isLocked(node): lockedAssets = True break # see if the selected node has any children and if so also check them for being locked. for childNode in node.allSubChildren(): if self.isLocked(childNode): lockedAssets = True break # If we found a locked assets lets tell the user and we can start doing the writing. if lockedAssets: hou.ui.displayMessage("you have a locked Node in your selection. the file will be saved but the data of that node will be lost.") code = "" for _node in hou.selectedNodes(): code += hou.hscript("opscript -r -b " + _node.path())[0] # Nasty Hack we need to do for VopSop. seems that the normal method of writing out the opscript method gives us # a problem where the settings will be lost because the vop's inside will automatically override the settings. # So we will get the settings for the VopSop and add it to the end just to make sure there being set! Damn SESI if self.needVopFix()[0]: for _node in self.needVopFix()[1:]: if not self.isVop(_node.parent()): addCode = hou.hscript("opscript -b " + _node.path())[0] if "opspareds" in addCode: asCode = "opcf " + _node.parent().path() + "\nopspareds" + addCode.split("opspareds")[1] code += asCode self._write(code, self._copyFile)
def setProject(project_dir = None): if project_dir: proj_dir = project_dir else: select_dir = hou.ui.selectFile(file_type = hou.fileType.Directory) if not select_dir: return False proj_dir = select_dir[:-1] hou.hscript("job %s" % proj_dir) return True
def copyTimeSettings( projName, seqName, shotName ): """copy time settings from animation file""" proj = prj.Project( projName ) seq = proj.sequence( seqName ) sht = seq.shot( shotName ) tim = sht.animPath.time fpsVals = {'pal':25,'film':24} hou.setFps( fpsVals[tim['tim']] ) cmd = 'tset `('+ str( tim[ 'ast' ] ) +'-1)/$FPS` `'+ str( tim[ 'aet' ] )+'/$FPS`' hou.hscript(cmd) hou.playbar.setPlaybackRange( tim[ 'ast' ], tim[ 'aet' ])
def _addNodeToBundle(self, node, **kwargs): bundleName = kwargs.get("bundleName", None) if not bundleName: return None bundle = hou.nodeBundle(bundleName) if not bundle: hou.hscript('opbadd "%s"' % bundleName) bundle = hou.nodeBundle(bundleName) if not bundle.containsNode(node): bundle.addNode(node)
def setPrefixForNewTakeNames(prefix_name='take'): ''' set the prefix used when vreating new takes''' hscript_cmd = 'takename -g' + prefix_name hou.hscript(hscript_cmd) hscript_cmd = 'setenv EYEVEXTOOLS_TAKE_PREFIX=' + prefix_name hou.hscript(hscript_cmd) result = prefix_name return None
def testSetTake(self): take = "take1" hou.hscript("takeadd %s" % take) self.assert_(take in IECoreHoudini.ActiveTake.ls()) self.assertNotEqual(take, IECoreHoudini.ActiveTake.name()) with IECoreHoudini.ActiveTake(take): self.assertEqual(take, IECoreHoudini.ActiveTake.name()) self.assertNotEqual(take, IECoreHoudini.ActiveTake.name())
def _set_magic_aovs_in_take(a_rfxAsset, magic_aovs): #Get current AOVs that are in used, and append them. aovs = a_rfxAsset.get_magic_aovs() for magic_aov in magic_aovs: if magic_aov.aov_name not in [aov.aov_name for aov in aovs]: aovs.append(magic_aov) #This is just a way to unlock those multi parms in takes. set_parms_in_take({'magic_aovs':40}, a_rfxAsset.sesi_node) set_parms_in_take({'magic_mattes':40}, a_rfxAsset.sesi_node) hou.hscript('takeinclude {0} *magic_*'.format(a_rfxAsset.sesi_node.path())) a_rfxAsset.set_magic_aovs(aovs) a_rfxAsset.set_use_magic_shaders(True)
def set_environment_variable(cls, var, value): """sets environment var :param str var: The name of the var :param value: The value of the variable """ os.environ[var] = value try: hou.allowEnvironmentVariableToOverwriteVariable(var, True) except AttributeError: # should be Houdini 12 hou.allowEnvironmentToOverwriteVariable(var, True) hscript_command = "set -g %s = '%s'" % (var, value) hou.hscript(str(hscript_command))
def addParmsFromTake(self, take, overwrite_existing=True): '''Include parameters from the specified Take in this Take.''' cur_take = curTake() cur_update_mode = hou.updateModeSetting() hou.setUpdateMode(hou.updateMode.Manual) setCurTake(self) force_flag = '' if overwrite_existing == True: force_flag = '-f ' source = take.name() hscript_cmd = 'takemerge ' + force_flag + ' ' + self._name + ' ' + source hscript_cmd_results = hou.hscript(hscript_cmd) if _takeErr(hscript_cmd_results[1]): result = hscript_cmd_results[1] else: result = None setCurTake(cur_take) hou.setUpdateMode(cur_update_mode) return result
def set_parms_in_take(parmsDict, node = None): """ Set values of parms in a take. parmsDict contains pairs of parms and values. ex.{'tx': '0', 'ty':'1', 'tz':2} If no node provided, the keys of parmDict have to be parm absolute paths. """ for parm_name in parmsDict: if not node: node = hou.parm(parm_name).node() hou.hscript('takeinclude {0} {1}'.format(node.path(), parm_name)) try: node.parm(parm_name).set(parmsDict[parm_name]) except AttributeError: print 'Unable to set parameter: {0}/{1}'.format(node.path(), parm_name)
def includeParms(self, parms, include=True): ''' Include given hou.Parm or hou.ParmTuple object(s) in the take. ''' if not hasattr(parms, "__iter__"): parms = [parms] self.setCurrent() include_flag = "" if not include: include_flag = "-u" for parm in parms: node = parm.node() node_path = node.path() parm_string = parm.name() result = hou.hscript("takeinclude {0} {1} {2}".format(include_flag, node_path, parm_string)) if result[1]: raise TakeSetError(result[1]) self._updateSavedData(node, parm)
def includeParmsFromTake(self, take, force=False): ''' Include all parms from a given take to this take. The take parameter can be either a Take object or a take name. force: (bool) Force a source take has the same included parameter as the destination, the source will overwrite the destination ''' if isinstance(take, Take): name = take.getName() else: name = take if name not in _listTakeNames(): raise TakeError("Can not find take: " + name) if force: force = "-f" else: force = "" result = hou.hscript("takemerge {0} {1} {2}".format(force, self.name, name)) if result[1]: raise TakeError(result[1]) tmp = dict(self.take_members.items() + take.getTakeMembers().items()) self.take_members = tmp return True
def set(): hipPath = os.path.dirname(hou.hipFile.name()) pathParts = getfolders(hipPath) #hipName = os.path.splitext(os.path.basename(hou.hipFile.name())[0] if pathParts[-1] != 'hip': raise hou.Error("hip file does not reside in a directory called 'hip', can't get job name") jobPath = os.path.join(os.path.split(hipPath)[0]) hou.hscript("setenv JOB=%s" % jobPath) jobName = pathParts[-2] hou.hscript('setenv JOBCACHE=E:/Projects/%s' % jobName)
def addJntSph(self): for i in xrange(self.polCount): for n in xrange(3): vidx = self.omd.idxList[self.polStart + i*3 + n] v = self.omd.vtxList[vidx] for j in xrange(len(v.idx)): jntId = v.idx[j] jntWgt = v.wgt[j] jnt = g_rig[jntId] sphName = "sph_" + jnt.name if not self.cullGeo.node(sphName): sphNode = self.cullGeo.createNode("sphere", sphName) sphNode.setParms({"type":5, "surftype":2}) # Primitive Type: Bezier, Connectivity: Rows and Columns sphNode.setParms({"orderu":3, "orderv":3, "imperfect":0}) sphNode.setParmExpressions({"rady":'ch("radx")', "radz":'ch("radx")'}) # Object Merge lnkName = "lnk_" + jnt.name; lnkNode = self.cullGeo.createNode("object_merge", lnkName) lnkNode.setParms({"xformpath":jnt.node.path(), "objpath1":sphNode.path()}) lnkNode.setParms({"invertxform":1}) # bsph = BSph(self, sphNode, lnkNode, jntId) self.sphList.append(bsph) self.sphMap[jntId] = bsph bsph = self.sphMap[jntId] bsph.update(vidx) # center (global) for bsph in self.sphList: bsph.estimate() # radius for i in xrange(self.polCount): for n in xrange(3): vidx = self.omd.idxList[self.polStart + i*3 + n] v = self.omd.vtxList[vidx] for j in xrange(len(v.idx)): jntId = v.idx[j] bsph = self.sphMap[jntId] bsph.grow(v.pos) for bsph in self.sphList: bsph.center = bsph.center - g_rig[bsph.jntId].wpos bsph.sphNode.setParms({"tx":bsph.center[0], "ty":bsph.center[1], "tz":bsph.center[2], "radx":bsph.radius}) # merge mrgNode = self.cullGeo.createNode("merge", "merge") hou.hscript("opset -d on " + mrgNode.path()) for bsph in self.sphList: mrgNode.setNextInput(bsph.lnkNode)
def _solveFullPath(self): hscript_cmd = 'takels' hscript_cmd_results = hou.hscript(hscript_cmd) # test for errors if _takeErr(hscript_cmd_results[1]): return None # list of heirarchillly indented takes indented_takes = hscript_cmd_results[0].split('\n') if indented_takes[-1]=='': del(indented_takes[-1]) # main loop name_found = False path_elements = [] levels_deep = None for i in range(len(indented_takes)): # work our way back from the end idx = (i+1)*-1 # find the leaf path element path_element = indented_takes[idx].lstrip() if self._name == path_element: name_found = True path_elements.insert(0,path_element) levels_deep = indented_takes[idx].count(' ') continue # leaf node unfound we keep looking elif name_found == False: continue # skip over siblings and children elif levels_deep <= indented_takes[idx].count(' '): continue else: # found the parent path_elements.insert(0,path_element) levels_deep = indented_takes[idx].count(' ') # list is empty -- notify before leaving if len(path_elements)==0: take_error =_takeErr('There is no take named: '+ self._name) result = None else: # join and return the path take_path = '/' + '/'.join(path_elements) result = take_path return result
def trAutoShow(): if hou.node("/obj/Trajectories")!=None: hou.hscript("undoctrl off") if len(hou.selectedNodes())>0: for obj in hou.node("/obj/Trajectories").children(): #t=None t=obj.parm("Object_Trajectory") if (hou.node(t.eval()).isSelected()==1) or (keyRight(t.eval())==1): if obj.isDisplayFlagSet()==0: obj.setDisplayFlag(1) dcolor=hou.node(obj.parm("Object_Trajectory").eval()).parmTuple("dcolor").eval() if dcolor!=obj.parmTuple("Trajectory_Color").eval(): obj.setParms({"Trajectory_Colorr":dcolor[0],"Trajectory_Colorg":dcolor[1],"Trajectory_Colorb":dcolor[2]}) else: if obj.isDisplayFlagSet()==1: obj.setDisplayFlag(0) else: for obj in hou.node("/obj/Trajectories").children(): if obj.isDisplayFlagSet()==1: obj.setDisplayFlag(0) hou.hscript("undoctrl on")
def returnToMainTake(): ''' Set Main take as current take. ''' result = hou.hscript("takeset Main") if result[1]: raise TakeSetError(result[1]) return True
def __init__(self,name=''): hscript_cmd = 'takeadd -v ' + name hscript_cmd_results = hou.hscript(hscript_cmd) if _takeErr(hscript_cmd_results[1]): return None name = hscript_cmd_results[0].rstrip() self._name = name self.setName(name)
def setCurrent(self): ''' Set take as current take. ''' result = hou.hscript("takeset " + self.name) if result[1]: raise TakeSetError("Take '{0}' not found.".format(self.name)) return True
def globalFramerange_main(self, **connections): try: range=[] fr=hou.hscript("frange") fr=fr[0] range.append(int(fr.split("Frame range: ")[1].split(" to")[0])) range.append(int(fr.split("to ")[1].strip())) return range except: return 0
def applyElementsAsString(elements, nodes): """Apply a list of elements at rendertime.""" value = listAsString(elements) for node in nodes: # Need to add the automatic aov parameters if they doesn't exist. if node.parm("auto_aovs") is None: # Add the parameters from the .ds file. hou.hscript( 'opproperty -f -F "Extra Image Planes" {0} ht_parms ht_automatic_aovs'.format( node.path() ) ) parm = node.parm("auto_aovs") parm.set(value) if node.parm("enable_auto_aovs") is not None: node.parm("enable_auto_aovs").set(True)
def applyCOPToBackground(scene_viewer, cop_node): """ Apply a COP node to the Scene Viewer background. """ view_path = buildViewPath(scene_viewer) hou.hscript("viewbackground -b on -S cop -C %s %s" % (cop_node.path(), view_path))
def applyImageToBackground(scene_viewer, file_path): """ Apply an image file to the Scene Viewer background. """ view_path = buildViewPath(scene_viewer) hou.hscript("viewbackground -b on -S file -F %s %s" % (file_path, view_path))
def viewwrite(options='', outpath='ip'): current_view = viewname() cmd = 'viewwrite {0} {1} {2}'.format(options, current_view, outpath) hou.hscript(cmd)
def take(self): if capp.HOST == capp.MAYA or capp.HOST == capp.MAYA2: view = omui.M3dView.active3dView() view.setColorMask(1, 1, 1, 0) width = view.portWidth() height = view.portHeight() image = om.MImage() if view.getRendererName() == view.kViewport2Renderer: image.create(view.portWidth(), view.portHeight(), 4, om.MImage.kFloat) view.readColorBuffer(image) image.convertPixelFormat(om.MImage.kByte) else: view.readColorBuffer(image) ptr = ctypes.cast(image.pixels().__long__(), ctypes.POINTER(ctypes.c_char)) ptrAsStr = ctypes.string_at(ptr, width * height * 4) image = QImage(ptrAsStr, width, height, QImage.Format_RGB32) image = image.mirrored(horizontal=False, vertical=True) self.img = QPixmap.fromImage(image) self.set(self.save(self.img)) elif capp.HOST == capp.NUKE: viewer = nuke.activeViewer() viewer_input = nuke.ViewerWindow.activeInput(viewer) viewer_node = nuke.activeViewer().node() if viewer_input is not None and viewer_node is not None: inputNode = nuke.Node.input(viewer_node, viewer_input) out_path = os.path.join(utils.tempdir(), "cerebro_screen.png").replace( '\\', '/') node_write = nuke.nodes.Write(file=out_path, name="cerebro_screen_node", file_type="png") node_write.setInput(0, inputNode) cur_frame = int(nuke.knob("frame")) nuke.execute(node_write.name(), cur_frame, cur_frame) self.set(out_path) # Cleanup for n in [node_write]: nuke.delete(n) elif capp.HOST == capp.HOUDINI: cur_desktop = hou.ui.curDesktop() frame = hou.frame() desktop = cur_desktop.name() panetab = cur_desktop.paneTabOfType( hou.paneTabType.SceneViewer).name() persp = cur_desktop.paneTabOfType( hou.paneTabType.SceneViewer).curViewport().name() camera_path = desktop + '.' + panetab + ".world." + persp out_path = os.path.join(utils.tempdir(), "cerebro_screen.jpg").replace('\\', '/') hou.hscript("viewwrite -r 800 600 -f {0} {1} {2} '{3}'".format( frame, frame, camera_path, out_path)) self.set(out_path) elif capp.HOST == capp.MAX: view = MaxPlus.ViewportManager.GetActiveViewport() bm = MaxPlus.Factory.CreateBitmap() storage = MaxPlus.Factory.CreateStorage(7) info = storage.GetBitmapInfo() bm.SetStorage(storage) bm.DeleteStorage() res = view.GetDIB(info, bm) if res: #bm.Display() out_path = os.path.join(utils.tempdir(), "cerebro_screen.jpg") info.SetName(out_path) bm.OpenOutput(info) bm.Write(info) bm.Close(info) self.set(out_path) elif capp.HOST == capp.C4D: xres, yres = 800, 600 doc = c4d.documents.GetActiveDocument() rd = c4d.documents.RenderData() rd[c4d.RDATA_XRES] = xres rd[c4d.RDATA_YRES] = yres rd[c4d.RDATA_RENDERENGINE] = c4d.RDATA_RENDERENGINE_PREVIEWHARDWARE bmp = c4d.bitmaps.BaseBitmap() if bmp.Init(xres, yres) == c4d.IMAGERESULT_OK: res = c4d.documents.RenderDocument(doc, rd.GetData(), bmp, c4d.RENDERFLAGS_EXTERNAL) if res == c4d.RENDERRESULT_OK: out_path = os.path.join(utils.tempdir(), "cerebro_screen.png") res = bmp.Save(out_path, c4d.FILTER_PNG) if res == c4d.IMAGERESULT_OK: self.set(out_path) elif capp.HOST == capp.BLENDER: out_path = os.path.join(utils.tempdir(), "cerebro_screen.png") for window in bpy.context.window_manager.windows: screen = window.screen for area in screen.areas: if area.type == 'VIEW_3D': for space in area.spaces: if space.type == 'VIEW_3D': for region in area.regions: if region.type == 'WINDOW': L_altBpyCtx = { # defining alternative context (allowing modifications without altering real one) 'area': area # our 3D View (first found) , 'blend_data': bpy.context. blend_data # just to suppress PyContext warning, doesn't seem to have any effect #, 'edit_text' : bpy.context.edit_text # just to suppress PyContext warning, doesn't seem to have any effect , 'region': None # just to suppress PyContext warning, doesn't seem to have any effect , 'scene': window.scene if utils.PY37 else screen.scene, 'space': space, 'screen': window.screen, 'window': window # current window, could also copy context } bpy.ops.screen.screenshot( L_altBpyCtx, filepath=out_path, check_existing=False, full=False) break #XXX: limit to the window of the 3D View break #XXX: limit to the corresponding space (3D View) break #XXX: limit to the first 3D View (area) self.set(out_path) elif capp.HOST == capp.STANDALONE: out_path = os.path.join(utils.tempdir(), "standalone_screen.png") if standalone.message_function("screenshot", [out_path])[0]: self.set(out_path) elif capp.HOST == capp.KATANA: out_path = os.path.join(utils.tempdir(), "cerebro_screen.png") wnd = capp.app_window() pix = QPixmap.grabWindow(wnd.winId()) pix.save(out_path) self.set(out_path) return self.img
def getChannelGroups(): lst = hou.hscript("chgls")[0].split() return lst
BP_RENDER_PATH = BP_BASE_PATH + '/2_production/3_render' BP_SCRIPTS_PATH = BP_PIPELINE_PATH + '/houdini/' BP_SHOTS_PATH = '{0}/2_production/2_shots'.format(BP_BASE_PATH) # Set / Get shot name BP_SHOT_NAME = '$BP_SHOT_NAME' try: hou.hscriptExpression(BP_SHOT_NAME) BP_SHOT_NAME_VALUE = hou.expandString('$BP_SHOT_NAME') except: hou.hscript('set -g BP_SHOT_NAME = {0}'.format('')) print('Initialized {0} to an empty value'.format(BP_SHOT_NAME)) # Set Environment # ----------------------------------------------------------------------------- try: hou.hscript('set -g BP_SHOT_NAME = {0}'.format(BP_SHOT_NAME)) hou.hscript('set -g BP_SHOTS_PATH = {0}'.format(BP_SHOTS_PATH)) hou.hscript('set -g BP_HDRI_PATH = {0}'.format(BP_HDRI_PATH)) hou.hscript('set -g BP_OTL_PATH = {0}'.format(BP_OTL_PATH)) hou.hscript('set -g BP_RENDER_PATH = {0}'.format(BP_RENDER_PATH)) hou.hscript('set -g JOB = {0}'.format(BP_SCRIPTS_PATH)) print('Environment variables set.')
workspace_file.close # Write out the render path : if renPath and os.path.isdir( renPath ) : try : nim_file=open( os.path.join( path, 'nim.mel' ), 'w' ) nim_file.write( renPath ) nim_file.close except : P.info( 'Sorry, unable to write the nim.mel file' ) ''' # Set Project : try: pathToSet = path.replace('\\', '/') + '/' if os.path.isdir(pathToSet): # update the environment variables os.environ.update({"JOB": str(pathToSet)}) # update JOB using hscript hou.hscript("set -g JOB = '" + str(pathToSet) + "'") hou.allowEnvironmentToOverwriteVariable("JOB", True) P.info('Current Project Set: %s\n' % pathToSet) else: P.info('Project not set!') except: pass return True # End
# This script is automatically run whenever Houdini starts. import hou import os try: testenv = os.environ['CURRENT_PROG'] except KeyError as ke: os.environ['CURRENT_PROG'] = 'Houdini' hou.hscript("unitlength 0.01;") hou.hscript("unitmass 0.01;")
def getJobParameters(afnode, subblock=False, frame_range=None, prefix=''): if VERBOSE: print('Getting Job Parameters from "%s":' % afnode.path()) # Process frame range: if frame_range is None: frame_first = int(hou.frame()) frame_last = frame_first frame_inc = 1 else: frame_first, frame_last, frame_inc = frame_range trange = afnode.parm('trange') if int(trange.eval()) > 0: frame_first = int(afnode.parm('f1').eval()) frame_last = int(afnode.parm('f2').eval()) frame_inc = int(afnode.parm('f3').eval()) frame_range = frame_first, frame_last, frame_inc params = [] connections = [] connections.extend(afnode.inputs()) nodes = [] for node in connections: if node is not None: nodes.append(node) output_driver_path = afnode.parm('output_driver').eval() if output_driver_path: output_driver = hou.node(output_driver_path) if output_driver: nodes.insert(0, output_driver) else: hou.ui.displayMessage('Can`t find output drive node: "%s"' % output_driver_path) if afnode.parm('cmd_mode').eval(): nodes.append(None) nodes.reverse() dependmask = '' prevparams = [] for node in nodes: if node and node.isBypassed(): continue newparams = [] if node and node.type().name() == 'afanasy': newprefix = node.name() if prefix != '': newprefix = prefix + '_' + newprefix newparams = getJobParameters(node, True, frame_range, newprefix) dependmask = newprefix + '_.*' if newparams is None: return None elif node and node.type().name() == "wedge": newprefix = node.name() if prefix != '': newprefix = prefix + '_' + newprefix wedgednode = None if node.inputs(): wedgednode = node.inputs()[0] else: wedgednode = node.node(node.parm("driver").eval()) if wedgednode == None: return None numWedges = computeWedge( node, node.type().name()) # we can remove nodetype check names = node.hdaModule().getwedgenames(node) for wedge in range(numWedges): # switching wedges like houdini do to get valid filenames hou.hscript('set WEDGE = ' + names[wedge]) hou.hscript('set WEDGENUM = ' + str(wedge)) hou.hscript('varchange') # add wedged node to next block block = getBlockParameters(afnode, wedgednode, subblock, "{}_{:02}".format(newprefix, wedge), frame_range)[0] block.auxargs += " --wedge " + node.path( ) + " --wedgenum " + str(wedge) newparams.append(block) # clear environment hou.hscript('set WEDGE = ') hou.hscript('set WEDGENUM = ') hou.hscript('varchange') dependmask = newprefix + '_.*' else: newparams = \ getBlockParameters(afnode, node, subblock, prefix, frame_range) if newparams is None: return None dependmask = newparams[0].name for param in newparams: if not param.valid: param.doPost() return None if len(newparams): params.extend(newparams) else: return None if not afnode.parm('independent').eval() and dependmask != '': for prevparam in prevparams: prevparam.addDependMask(dependmask) prevparams = newparams # Last parameter needed to generate a job. if not subblock: params.append( BlockParameters(afnode, None, False, '', frame_range, True)) return params
def getMinFrame(): return int(hou.hscript("frange")[0].split()[2])
def paste_clipboard_to_netview(kwargs): """Paste clipboard contents (text or image) into the network editor. """ clipboard = Qt.QtGui.QGuiApplication.clipboard() image = clipboard.image() text = clipboard.text() pane = kwargs.get('editor', None) if pane: pwd = pane.pwd() if image.isNull(): # paste text (if any) if text != "": note = pwd.createStickyNote() note.move(pane.visibleBounds().center()) s = note.size() s = hou.Vector2(( s.x() * 1.5, s.y() * 0.5, )) note.setText(text) note.setSize(s) else: # paste image # generate automatic name image_name = 'image_' + datetime.datetime.now().replace( microsecond=0).isoformat('_').replace(":", "") msg = [] images = sorted(get_existing_images(kwargs)) if len(images) > 0: msg.append("Existing images:") c = 0 for i in images: msg.append(" - %s" % i) c += 1 if c >= 20: break if c < len(images): msg.append(" - (...) ") msg.append( '\n(Images are stored in an embedded "qLib::embedded_images" /obj node).' ) msg = "\n".join(msg) ok, image_name = hou.ui.readInput( "Enter name of image to be pasted", buttons=( 'Ok', 'Cancel', ), close_choice=1, help=msg, initial_contents=image_name) if image_name == '': ok = 1 image_name += '.png' if ok == 0: hda_typename = embedded_hda_typename() hda_def = get_embedded_img_hdadef() # create hda definition if doesn't exist if not hda_def: temp_node = hou.node('/obj').createNode('subnet') hda_node = temp_node.createDigitalAsset( name=hda_typename, save_as_embedded=True) hda_node.destroy() hda_def = get_embedded_img_hdadef() # create an instance in /obj if doesn't exist node = None nodes = [ n for n in hou.node('/obj').children() if n.type().name() == hda_typename ] if len(nodes) == 0: node = hou.node('/obj').createNode( hda_typename, node_name="embedded_images") node.setComment( "embedded BG images for network views\n(do not delete)" ) hou.hscript("opset -Y on %s" % node.path()) pass # set comment "do not delete" # add clipboard image to hda definition (as section) ba = Qt.QtCore.QByteArray() buffer = Qt.QtCore.QBuffer(ba) buffer.open(Qt.QtCore.QIODevice.WriteOnly) image.save(buffer, "png") buffer.close() hda_def.addSection(image_name, str(buffer.data())) # add image to network view add_image_to_netview(embedded_img_prefix(image_name), pane, pwd)
def set_namespace_aliases(prefix="qLib::", alias=True, verbose=False): """ Defines (non-)namespaced aliases for operators with a particular namespace prefix. This is used for always creating the namespaced versions of assets, even if an older .hip file contains non-namespaced asset names. Mapping looks like: <opname> --> <prefix>::<opname>::<version> @note IMPORTANT: Although the manual says it's fine to omit the version of a namespaced asset (and that would refer to the latest version), omitting it results in files getting messed up when loaded, so version numbers _are_ included in the opaliases. @note This function should be called (preferably) on Houdini startup, e.g. import qlibutils qlibutils.set_namespace_aliases( ["qLib::", "myStuff::"] ) @todo For each asset, the highest version number should be found and used. Right now it uses the first version it founds (which is fine for now). """ if type(prefix) is list: for p in prefix: set_namespace_aliases(p) return assert "::" in prefix, "Include trailing '::' characters in prefix" cmds = [] for file in hou.hda.loadedFiles(): names = [(d.nodeType().name(), d.nodeTypeCategory().name()) for d in list(hou.hda.definitionsInFile(file)) if prefix in d.nodeType().name()] for n in names: try: # strip namespace prefix and version suffix old = re.sub("^[^:]+::", "", n[0]) old = re.search("^[^:]+", old).group(0) # opalias <network> <namespaced-op.> <plain-old-op.> cmd = "opalias %s %s %s" % (n[1], n[0], old) if cmd not in cmds: if verbose: print cmd if alias: hou.hscript(cmd) cmds.append(cmd) else: print "# ALREADY ALIASED: %s (%s)" % (cmd, file) except: print "ERROR: %s" % traceback.format_exc()
def getChannelsInGroup(grpName): lst = hou.hscript("chgls -l " + grpName)[0].split() if len(lst): del lst[0] # remove group name from the list return lst
def getMaxFrame(): return int(hou.hscript("frange")[0].split()[4])
# Loading HIP file, and force HIP variable: force_hip = False # not sure, we need to force HIP variable. # May be this code is obsolete if force_hip: envhip = os.path.abspath(hip) envhip = os.path.dirname(envhip) if os.name != 'nt': envhip = envhip.replace('\\\\', '/') # for nt //server/share/path is # the only one way envhip = envhip.replace('\\', '/') # houdini always use unix-like path os.environ['HIP'] = envhip hou.allowEnvironmentToOverwriteVariable('HIP', True) hou.hscript('set HIP=' + envhip) # Note that we ignore all load warnings. try: hou.hipFile.load(hip) except hou.LoadWarning: pass # hou.hipFile.load( hip, True) if force_hip: hou.hscript('set HIPNAME=%s' % os.path.basename(hip)) hou.hscript('set HIP=%s' % envhip) print('HIP set to "%s"' % envhip) # Establish ROP to be used if rop[0] != '/':
def setupMutationFromMarkedWedges(marked_idx_list, wedge_anchor_node, mode): print "\n\nSetup Starting...\n" idx_list = marked_idx_list wedge_node = wedge_anchor_node num_wedges = len(idx_list) setup_mode = mode #print mode if setup_mode == 0: print "Mode: Convert to Takes (del. existing Takes)\n" elif setup_mode == 1: print "Mode: Convert to Takes (keep existing Takes)\n" elif setup_mode == 2: print "Mode: Convert to TOP Wedge (del. existing Takes)\n" #get current update mode update_mode_set = hou.updateModeSetting() #set update mode to manual hou.setUpdateMode(hou.updateMode.Manual) #set auto takes on hou.hscript("takeautomode on") #get root take roottake = hou.takes.rootTake() print "Root Take: {}".format(roottake.name()) #cook pdg node first pdgnode = wedge_node.getPDGNode() #generate static items first to be able to access wedge_node.generateStaticItems() time.sleep(1.5) work_items = pdgnode.staticWorkItems if setup_mode == 0 or setup_mode == 2: #remove all existing takes first takes = roottake.children() for take in takes: take.destroy() #convert wedges to takes for idx in idx_list: take = roottake.addChildTake(idx) hou.takes.setCurrentTake(take) selectWedgeIndex(idx, wedge_node, work_items) #return to root take hou.takes.setCurrentTake(roottake) #reset update mode hou.setUpdateMode(update_mode_set) #set auto takes off hou.hscript("takeautomode off") print "\nSuccessfully converted Wedges to Takes\n" #if mode is Convert to TOP Wedge if setup_mode == 2: #create new wedge node in same Topnet as wedge_anchor_node topnet = wedge_node.parent() new_wedge_node = topnet.createNode("wedge", "wedge_base_from_marked") new_wedge_node.setPosition(wedge_node.position()) new_wedge_node.move([-5, 0]) #new_wedge_node.setSelected(1, clear_all_selected=True) remove_takes = True convertTakesToWedge(new_wedge_node, remove_takes)
def __onCreateProxy(self): # @brief builds cmdline args for vrayproxy cmd based on UI options and calls it # @note see vfh_home/help/command.help file or type 'help vrayproxy' in textport # for detailed info on vrayproxy usage and command line options. cmd_args = "-n {}".format( hou.expandString(self.__ui.value("filepath.val"))) if bool(self.__ui.value("mkpath.val")): cmd_args += " -c" if bool(self.__ui.value("overwrite.val")): cmd_args += " -f" if bool(self.__ui.value("exp_separately.val")): cmd_args += " -m" if bool(self.__ui.value("save_hidden.val")): cmd_args += " -i" if bool(self.__ui.value("lastaspreview.val")): cmd_args += " -l" if bool(self.__ui.value("xformtype.val")): cmd_args += " -t" if bool(self.__ui.value("exp_animation.val")): # animplayback is one of {0 = Use playback range, 1 = Use animation range, 2 = User specified range } animPlayback = self.__ui.value("animplayback.val") animStart = 0 animEnd = 0 if animPlayback == 0: animStart = int(hou.expandString('$RFSTART')) animEnd = int(hou.expandString('$RFEND')) elif animPlayback == 1: animStart = int(hou.expandString('$FSTART')) animEnd = int(hou.expandString('$FEND')) elif animPlayback == 2: animStart = self.__ui.value("animstart.val") animEnd = self.__ui.value("animend.val") cmd_args += " -a {} {}".format(animStart, animEnd) exportVelocity = bool(self.__ui.value("exp_velocity.val")) if exportVelocity: velocityStart = self.__ui.value("velocitystart.val") velocityEnd = self.__ui.value("velocityend.val") cmd_args += " -v {} {}".format(velocityStart, velocityEnd) cmd_args += " -T {} -F {} -H {}".format( self.__ui.value("simplificationtype.val"), self.__ui.value("max_previewfaces.val"), self.__ui.value("max_previewstrands.val")) if not bool(self.__ui.value("voxelpermesh.val")): maxFacesPerVoxel = self.__ui.value("max_facespervoxel.val") cmd_args += " -X {}".format(maxFacesPerVoxel) if bool(self.__ui.value("exp_pcls.val")): pointSize = self.__ui.value("pointsize.val") cmd_args += " -P {}".format(pointSize) cmd_args += " {}".format(self.__ui.value("objects.val")) print("Calling: vrayproxy {}".format(cmd_args)) res = hou.hscript("vrayproxy {}".format(cmd_args)) print("\n".join(res)) self.show(0)
def _getProject(self): p_path = (hou.hscript('echo $JOB')[0])[:-1] # [:-1] is for the extra \n norm_p_path = os.path.normpath(p_path) return norm_p_path
def setEnvValue(): engine = sgtk.platform.current_engine() print engine.context.entity_locations workPath = engine.context.entity_locations if len(workPath) == 0: return else: workPath = workPath[0] workPath = workPath.replace('\\', '/') print workPath match = re.match( 'P:/Project/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)', workPath) if match is None: return proj = match.group(1) roll = match.group(3) sequence = match.group(4) cut = match.group(5) hou.hscript('setenv -g PROJ = %s' % proj) hou.hscript('setenv -g SHOT = %s' % sequence) hou.hscript('setenv -g CUT = %s' % cut) user = os.environ['USERNAME'] hou.hscript('setenv -g USER = %s' % user) cachePath = os.path.join('P:/CACHE', proj, user).replace('\\', '/') hou.hscript('setenv -g CACHE = %s' % cachePath) currentHip = hou.hipFile.basename() print currentHip if 'untitled' in currentHip: ver = 'v001' elem = 'efx' else: match = re.match('([a-zA-Z0-9]+)_([a-zA-Z0-9]+)_(v[0-9]+)', currentHip) print match if match is None: ver = 'v001' elem = 'efx' else: ver = match.group(3) elem = match.group(2) hou.hscript('setenv -g VER = %s' % ver) hou.hscript('setenv -g ELEM = %s' % elem) take = hou.getenv('TAKE', 't01') hou.hscript('setenv -g TAKE = %s' % take)
def render(root, passes=[], to_render=True): """ Create Mantra ROPs and apply settings """ selected_nodes = hou.selectedNodes() clean_tmp_geoms() #Get takes in Main. take_list = hou.hscript('takels -i -q -p Main')[0].split('\n')[:-1] layers = root.find(type='Pass') mantras = [] #Create and setting Mantras for layer in layers: #Only render selected passes when user specified. if passes and layer['name'] not in passes: continue # Make sure we are doing everyting starts with Main take hou.hscript('takeset Main') #For each pass we create a Mantra ROP for it. mantra = Mantra(layer) #Move the node posititon mantra_ROP = create_Mantra_ROP(mantra, pos=(0, layers.index(layer) * -1)) #Create all the temp objs we need for this render create_tmp_geoms(mantra) #Set mantra parms apply_mantra_settings(mantra, mantra_ROP) #Add render objects to Mantra set_parms_in_take({'vobject': ''}, node=mantra_ROP) for render_mode in OBJECT_MODE_MAP: set_render_objects(mantra, mantra_ROP, OBJECT_MODE_MAP[render_mode]) #Add render lights to Mantra set_parms_in_take({'alights': ''}, node=mantra_ROP) forcelights = '' for light in mantra.lights: forcelights = '{0} {1} '.format(light.obj_path, forcelights) set_parms_in_take({'forcelights': forcelights}, node=mantra_ROP) #Create a NEW take from Main for each Mantra ROP hou.hscript('takeautomode off') if mantra.name in take_list: hou.hscript('takerm {0} -R'.format(mantra.name)) hou.hscript('takeadd -c -p Main {0}'.format(mantra.name)) #Set camera shutter speed if mantra.mantra_settings.has_key( 'shutter') and mantra.mantra_settings['shutter']: set_parms_in_take({'shutter': mantra.mantra_settings['shutter']}, node=mantra.camera) #Set camera crop cropmask = '* ' cropmask += list_to_string(mantra.no_mask_objs, exclude=True) set_parms_in_take({'cropmask': cropmask}, node=mantra.camera) #RFXcamera does something magic and set the translate parms when rendering. #Allow those parms being modified in the take. if rfxAbcCamera.is_rfx_abc_camera(mantra.camera): hou.hscript('takeinclude {0} *'.format(mantra.camera.path())) #Set object parms apply_object_settings(mantra) #We need to get magic_aovs for future use, also magic_aoves must be queried in take #We don't need it anymore since we have that handled in SOHO #magic_aovs = mantra.get_rendered_magic_aovs() #Set light parms apply_light_settings(mantra) hou.hscript('takeset Main') hou.hscript('takeautomode off') #Set the magic shader image planes after setting objests. Must do #This has been handled in SOHO #set_magic_shader_planes(mantra, magic_aovs) #Set render take for this pass in Main mantra_ROP.parm('take').set(mantra.name) mantras.append(mantra_ROP) #Set back to Main take hou.hscript('takeset Main') #Set back User selected nodes try: for node in selected_nodes: node.setSelected(True) except: pass if to_render: for mantra_ROP in mantras: mantra_ROP.render() return mantras
def apply_object_settings(mantra): """ Apply HRST object settings to Mantra """ for obj in mantra.objects: objNode = hou.node(obj.obj_path) if objNode: for setting in obj.settings: #Regular set parms if setting not in OBJECT_SPECIAL_SETTINGS: set_parms_in_take({setting: obj.settings[setting]}, node=objNode) #Magic AOV set parms, Bty pass only elif setting == 'matte_aovs' and obj.rfxAssets: for a_rfxAsset in obj.rfxAssets: render_aovs = [ aov for aov in a_rfxAsset.get_imported_magic_aovs() if aov.aov_name in obj.settings[setting] ] _set_magic_aovs_in_take(a_rfxAsset, render_aovs) #Set global OBJ settings #Reflection set parms if objNode and mantra.no_reflection_objects: no_reflection = '* ' no_reflection += list_to_string(mantra.no_reflection_objects, exclude=True) set_parms_in_take({'reflectmask': no_reflection}, node=objNode) #Refraction set parms if objNode and mantra.no_refraction_objects: no_refraction = '* ' no_refraction += list_to_string(mantra.no_refraction_objects, exclude=True) set_parms_in_take({'refractmask': no_refraction}, node=objNode) #Do shadow pass if objNode and mantra.pass_type == 'shadow': #Create shadow map shader for render shadow_matte_SHOP = hou.node( '/shop/{0}'.format(TMP_SHADOW_MATTE_NAME)) if not shadow_matte_SHOP or not shadow_matte_SHOP.type().name( ) == 'v_shadowmatte': shadow_matte_SHOP = hou.node('/shop/').createNode( 'v_shadowmatte', TMP_SHADOW_MATTE_NAME) #Set shadow matte shader to all the visible object. if obj.render_mode == 'forceobject': #Regular objects set_parms_in_take( {'shop_materialpath': shadow_matte_SHOP.path()}, node=objNode) #RFX Objects. #We have to turn off look in rfxAsset SOP in order to show the shadow map. for a_rfxAsset in obj.rfxAssets: set_parms_in_take({'import_look': False}, a_rfxAsset.sesi_node) #Do matte pass elif objNode and mantra.pass_type == 'matte': #Find the rfxAsset SOP and get Magic Aovs. if not obj.obj_path == obj.HRST_path: render_node = objNode.renderNode() numobj = render_node.parm('numobj').eval() for num in range(1, numobj + 1): obj_path = render_node.parm( 'objpath{0}'.format(num)).eval() if obj_path == obj.HRST_path: #For each HRST objects, we need to put all the geometry parts in one channel. #We name the AOV for each object all same here. for a_rfxAsset in obj.rfxAssets: groups = render_node.parm( 'group{0}'.format(num)).eval() magic_aov = look_utils.MagicAov(groups, obj.name) _set_magic_aovs_in_take(a_rfxAsset, [magic_aov]) #The magic matte should be always * when render with matte pass a_rfxAsset.set_magic_matte_shader('*') break else: for a_rfxAsset in obj.rfxAssets: magic_aov = look_utils.MagicAov('*', obj.name) _set_magic_aovs_in_take(a_rfxAsset, [magic_aov]) #The magic matte should be always * when render with matte pass a_rfxAsset.set_magic_matte_shader('*') #Do ambient occlusion pass elif objNode and mantra.pass_type == 'ambientOcclusion': HRST_Node = hou.node(obj.HRST_path) render_node = HRST_Node.renderNode() if render_node.name() == "AO_ATTR": render_node = render_node.inputs()[0] if render_node.geometry() and 'shop_materialpath' not in [ attr.name() for attr in render_node.geometry().primAttribs() ]: return #Create a Attribute Node so it can hook with rfx SOHO code attri_AO_SOP = HRST_Node.node("AO_ATTR") if not attri_AO_SOP: attri_AO_SOP = HRST_Node.createNode("attribcreate::2.0", "AO_ATTR") attri_AO_SOP.setInput(0, render_node) #This is the way we add render flag in a take if not attri_AO_SOP.isRenderFlagSet(): hou.hscript('takeinclude -r {0}'.format(attri_AO_SOP.path())) hou.hscript('takeinclude -r {0}'.format(render_node.path())) attri_AO_SOP.setRenderFlag(True) attri_AO_SOP_settings = { 'numattr': 1, 'name1': 'shop_materialpath', 'class1': 1, 'type1': 3, 'string1': '`ifs(hasprimattrib("{0}", "shop_materialpath"), prims("{0}", $PR, "shop_materialpath")/__OCCLUSION__, "")`' .format(render_node.path()) } set_parms_in_take(attri_AO_SOP_settings, attri_AO_SOP) attri_AO_SOP.hide(True)
def refreshGlCache(): hou.hscript('glcache -c')
def show_panel(self, panel_id, title, bundle, widget_class, *args, **kwargs): """Show the panel matching the supplied args. Will first try to locate an existing instance of the panel. If it exists, it will make it current. If it can't find an existing panel, it will create a new one. If the panel can't be created for some reason, the widget will be displayed as a dialog. :param panel_id: Unique id to associate with the panel - normally this is a string obtained via the register_panel() call. :param title: The title of the window :param bundle: The app, engine or framework object that is associated with this window :param widget_class: The class of the UI to be constructed. This must derive from QWidget. Additional parameters specified will be passed through to the widget_class constructor. """ # check to see if we just need to return the widget itself. Since we # don't really have information about the panel outside of this call, # we use a special flag to know when the info is needed and return it. if hasattr(self, '_panel_info_request') and self._panel_info_request: return { 'id': panel_id, 'title': title, 'bundle': bundle, 'widget_class': widget_class, 'args': args, 'kwargs': kwargs, } # try to locate the pane in the desktop and make it the current tab. for pane_tab in hou.ui.curDesktop().paneTabs(): if pane_tab.name() == panel_id: pane_tab.setIsCurrentTab() return # panel support differs between 14/15. if self._panels_supported(): # if it can't be located, try to create a new tab and set the # interface. panel_interface = None try: for interface in hou.pypanel.interfacesInFile( self._panels_file): if interface.name() == panel_id: panel_interface = interface break except hou.OperationFailed: # likely due to panels file not being a valid file, missing, etc. # hopefully not the case, but try to continue gracefully. self.log_warning( "Unable to find interface for panel '%s' in file: %s" % (panel_id, self._panels_file)) if panel_interface: # the options to create a named panel on the far right of the # UI doesn't seem to be present in python. so hscript it is! # Here's the docs for the hscript command: # https://www.sidefx.com/docs/houdini14.0/commands/pane hou.hscript("pane -S -m pythonpanel -o -n %s" % panel_id) panel = hou.ui.curDesktop().findPaneTab(panel_id) # different calls to set the python panel interface in Houdini # 14/15 if hou.applicationVersion()[0] >= 15: panel.setActiveInterface(panel_interface) else: # if SESI puts in a fix for setInterface, then panels # will work for houini 14. will just need to update # _panels_supported() to add the proper version. and # remove this comment. panel.setInterface(panel_interface) # turn off the python panel toolbar to make the tk panels look # more integrated. should be all good so just return panel.showToolbar(False) return # if we're here, then showing as a panel was unsuccesful or not # supported. Just show it as a dialog. self.show_dialog(title, bundle, widget_class, *args, **kwargs)
def move_to_frame(frame): hou.hscript("fcur %d" % frame) hou.hscript("updateui")
def __init__(self, selected_node=None, create_light=True, assets_grid=None, current_category=None, parent=None): super(CreateNewEntryWidget, self).__init__(parent, QtCore.Qt.WindowStaysOnTopHint) self.setWindowTitle("Create new asset") self.setWindowIcon(get_icon("populate_database")) self.setAutoFillBackground(True) self.setProperty("houdiniStyle", True) self.assets_grid = assets_grid self.current_category = current_category self.selected_node = selected_node self.nprims = -1 self.npoints = -1 self.bounds = [] self.obj_center = [] self.light_scale = 1 self.obj_geo = None self.get_object_infos() main_layout = QtWidgets.QVBoxLayout() # create light node if needed self.light_node = None if create_light: self.light_node = hou.node("obj/Gaia_3pts_light") if not self.light_node: self.light_node = hou.node("/obj").createNode( "three_point_light", "Gaia_3pts_light") self.light_node.setDisplayFlag(False) self.light_node.parm("scale").set(self.light_scale) # Init view selected_node.setDisplayFlag(True) self.nodes_state = [n for n in hou.node("/obj").children() \ if n.isDisplayFlagSet() \ and n != selected_node] for n in self.nodes_state: n.setDisplayFlag(False) self.selected_node.setCurrent(True) self.selected_node.setSelected(True) viewer = toolutils.sceneViewer() viewport = viewer.curViewport() viewport.frameSelected() self.aspec = viewport.settings().viewAspectRatio() self.viewer_p = nodeInfos.get_viewer_fullpath() hou.hscript( ("viewtransform " + self.viewer_p + " flag ( +a ) aspect ( 1.0 )")) # thumbnail layout thumbnail_lay = QtWidgets.QHBoxLayout() thumbnail_lay.setSpacing(5) snap_lay = QtWidgets.QVBoxLayout() snap_lay.setAlignment(QtCore.Qt.AlignTop) snap_lay.setSpacing(5) self.thumbnail = QtWidgets.QLabel("") self.thumbnail.setFixedWidth(150) self.thumbnail.setFixedHeight(150) self.thumbnail.setStyleSheet("""QLabel{border: 1px solid black}""") self.thumbnail_pix = get_icon("close").pixmap(1, 1) self.thumbnail.setPixmap(self.thumbnail_pix) snap_lay.addWidget(self.thumbnail) # basic geo infos snap_lay.addWidget(h_widgets.HSeparator()) snap_lay.addWidget(QtWidgets.QLabel("Points: {}".format(self.npoints))) snap_lay.addWidget(QtWidgets.QLabel("Prims: {}".format(self.nprims))) binfos = "Bounds:\t {0:.2f} ".format(self.bounds[1]) binfos += "{0:.2f} ".format(self.bounds[3]) binfos += "{0:.2f} ".format(self.bounds[5]) snap_lay.addWidget(QtWidgets.QLabel(binfos)) binfos = "\t {0:.2f} ".format(self.bounds[0]) binfos += "{0:.2f} ".format(self.bounds[2]) binfos += "{0:.2f}".format(self.bounds[4]) snap_lay.addWidget(QtWidgets.QLabel(binfos)) center = "Center: {0:.2f} ".format(self.obj_center[0]) center += "{0:.2f} ".format(self.obj_center[1]) center += "{0:.2f}".format(self.obj_center[2]) snap_lay.addWidget(QtWidgets.QLabel(center)) thumbnail_lay.addItem(snap_lay) thumbnail_lay.addWidget(h_widgets.HSeparator(mode="vertical")) thumbnail_opts_lay = QtWidgets.QVBoxLayout() thumbnail_opts_lay.setSpacing(5) thumbnail_opts_lay.setAlignment(QtCore.Qt.AlignTop) if self.light_node: self.light_orient = h_widgets.HSlider( "light orientation", min=0.0, max=360, lock_min=True, lock_max=True, hou_parm=self.light_node.parm("ry")) thumbnail_opts_lay.addWidget(self.light_orient) self.capture_btn = QtWidgets.QPushButton("Update Snapshot") self.capture_btn.setIcon(get_icon("terrain")) self.capture_btn.clicked.connect(self.create_thumbnail) thumbnail_opts_lay.addWidget(self.capture_btn) thumbnail_opts_lay.addWidget(h_widgets.HSeparator()) self.name = h_widgets.HStringValue(self.selected_node.name(), "name:") thumbnail_opts_lay.addWidget(self.name) self.tags = h_widgets.HStringValue("", "tags:") thumbnail_opts_lay.addWidget(self.tags) self.category = QtWidgets.QLabel("Category: " + self.current_category) thumbnail_opts_lay.addWidget(self.category) format_lay = QtWidgets.QHBoxLayout() format_lay.setSpacing(5) format_lay.setAlignment(QtCore.Qt.AlignLeft) format_lay.addWidget(QtWidgets.QLabel("Format:")) self.format = QtWidgets.QComboBox() self.format.addItems(["bgeo.gz", "obj", "abc", "hda"]) format_lay.addWidget(self.format) thumbnail_opts_lay.addLayout(format_lay) type_lay = QtWidgets.QHBoxLayout() type_lay.setSpacing(5) type_lay.setAlignment(QtCore.Qt.AlignLeft) type_lay.addWidget(QtWidgets.QLabel("Type:")) self.obj_type = QtWidgets.QComboBox() self.obj_type.addItems(["static", "dynamic", "animated"]) type_lay.addWidget(self.obj_type) thumbnail_opts_lay.addLayout(type_lay) thumbnail_opts_lay.addWidget(QtWidgets.QLabel("Infos:")) self.info_text = QtWidgets.QTextEdit() self.info_text.setMaximumHeight(75) thumbnail_opts_lay.addWidget(self.info_text) thumbnail_lay.addItem(thumbnail_opts_lay) main_layout.addItem(thumbnail_lay) # footer buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.setSpacing(5) self.validate_btn = QtWidgets.QPushButton("Create Asset") self.validate_btn.clicked.connect(self.create_asset) self.validate_btn.setIcon(get_icon("checkmark")) buttons_layout.addWidget(self.validate_btn) self.cancel_btn = QtWidgets.QPushButton("Cancel") self.cancel_btn.clicked.connect(self.close) self.cancel_btn.setIcon(get_icon("close")) buttons_layout.addWidget(self.cancel_btn) main_layout.addLayout(buttons_layout) self.setLayout(main_layout) self.thumbnail_data = "" self.create_thumbnail()
# Import fbx files import os import hou job = os.environ['JOB'] geo_dir = job + '/geo/work' files = os.listdir(geo_dir) for file in files: if file.endswith('.fbx'): hou.hscript("fbximport '%s'" % (geo_dir + '/' + file))
def copyToNewProject(newProject, choose=False): hipPath = hou.hipFile.name() oldProject = hou.hscript("echo $JOB")[0][:-1] def pathForExport(): allPath = hou.hscript("opextern -rR -g -l /")[0].split("\n")[:-1] selectedPath = [] if choose: selectedItem = hou.ui.selectFromList(allPath) for item in selectedItem: path = allPath[item] selectedPath.append(path) else: selectedPath = allPath return selectedPath def expandSequence(allPath): allPathExpanded = [] for path in allPath: match = re.search(r"\[.+\]", path) if match: frameRange = re.findall("\d+", match.group()) seqPath = path[:-len(match.group()) - 2] seqDir = os.path.split(seqPath)[0] if os.path.isdir(seqDir): filesInDir = os.listdir(seqDir) for file in filesInDir: filePath = seqDir + "/" + file allPathExpanded.append(filePath) else: print seqDir, "- Folder do not exist" else: allPathExpanded.append(path) return allPathExpanded def deleteMissingPaths(allPaths): allPathsCleaned = [] for path in allPaths: if os.path.exists(path): allPathsCleaned.append(path) return allPathsCleaned selectedPath = pathForExport() allPathExpanded = expandSequence(selectedPath) allPath = deleteMissingPaths(allPathExpanded) allPath.append(hipPath) # Create folders for path in allPath: if os.path.isfile(path): newFilePath = path.replace(oldProject, newProject) newPath = os.path.split(newFilePath)[0] if len(newPath) > 0: if not os.path.isdir(newPath): os.makedirs(newPath) if not os.path.isfile(newFilePath): shutil.copyfile(path, newFilePath) print newFilePath, "- File has been created" else: print newFilePath, "- File is already exist" else: print path, "- Do not exist" print "DONE!"
def genJob(self, blockparams): if VERBOSE: print('Generating job on "%s"' % self.job_name) if len(blockparams) < 1: print('Can`t generate job without any blocks on "%s"' % self.afnode.name()) return job = af.Job() job.setName(self.job_name) if self.afnode.parm('wait_time').eval(): hours = int(self.afnode.parm('wait_time_hours').eval()) minutes = int(self.afnode.parm('wait_time_minutes').eval()) hours = max(0, min(hours, 23)) minutes = max(0, min(minutes, 59)) now_sec = int(time.time()) now_day = int((now_sec - time.timezone) / (24 * 3600)) * (24 * 3600) + time.timezone sec = now_sec % 60 wait_sec = now_day + (hours * 3600) + (minutes * 60) + sec if wait_sec <= now_sec: result = hou.ui.displayMessage( 'Now is greater than %d:%d\nOffset by 1 day?' % (hours, minutes), buttons=('Offset', 'Abort'), default_choice=0, close_choice=1, title='Wait Time') if result == 0: wait_sec += (24 * 3600) else: return job.setWaitTime(wait_sec) renderhip = hou.hipFile.name() if self.afnode.parm('render_temp_hip').eval(): # Calculate temporary hip name: ftime = time.time() renderhip = '%s/%s%s%s.hip' % ( os.path.dirname(renderhip), afcommon.filterFileName(self.job_name), time.strftime('.%m%d-%H%M%S-'), str(ftime - int(ftime))[2:5]) # use mwrite, because hou.hipFile.save(renderhip) # changes current scene file name to renderhip, # at least in version 9.1.115 hou.hscript('mwrite -n "%s"' % renderhip) if self.start_paused: job.offLine() if self.preview_approval: job.setPPApproval() if self.platform != '': if self.platform == 'any': job.setNeedOS('') else: job.setNeedOS(self.platform) if self.job_branch != '': job.setBranch(self.job_branch) if self.priority != -1: job.setPriority(self.priority) if self.depend_mask != '': job.setDependMask(self.depend_mask) if self.depend_mask_global != '': job.setDependMaskGlobal(self.depend_mask_global) if self.max_runtasks > -1: job.setMaxRunningTasks(self.max_runtasks) if self.maxperhost > -1: job.setMaxRunTasksPerHost(self.maxperhost) if self.hosts_mask != '': job.setHostsMask(self.hosts_mask) if self.hosts_mask_exclude != '': job.setHostsMaskExclude(self.hosts_mask_exclude) if self.life_time > -1: job.setTimeLife(self.life_time * 3600) # hours to seconds job.setFolder('input', os.path.dirname(hou.hipFile.name())) images = None for blockparam in blockparams: job.blocks.append(blockparam.genBlock(renderhip)) # Set output folder from the first block with images to preview: if images is None and blockparam.preview != '': images = blockparam.preview job.setFolder('output', os.path.dirname(images)) if self.afnode.parm('render_temp_hip').eval(): job.setCmdPost('deletefiles "%s"' % renderhip) if VERBOSE: job.output(True) job.send()
globs['PLAY'] = '{0}/flipbook/{1}'.format(globs['JOB'], shotDir) globs['PERFORCE'] = '{0}/{1}.ma'.format(LOCAL_MAYA_SCENES, shotDir) globs['WRANGLE'] = '{0}/vex_wrangles/{1}'.format(globs['JOB'], shotDir) globs['PROXY'] = '{0}/proxy/{1}'.format(globs['JOB'], shotDir) globs['MRENDER'] = '{0}/OppositeLayer/MasterBeauty'.format( globs['RCPATH']) globs['LS'] = '{0}/RND_files/render_{1}_master/LS'.format( globs['MJOB'], globs['SEQ']) globs['REFPATH'] = '{0}/references/{1}'.format(globs['JOB'], shotDir) globs['_EXPORT'] = '{0}/_Export/{1}'.format(globs['JOB'], shotDir) else: globs['HDATA'] = '{0}/data'.format(HIP) globs['HDATA_GLOB'] = '{0}/data'.format(HIP) globs['MDATA'] = '{0}/geo'.format(HIP) globs['PLAY'] = '{0}/flipbook'.format(HIP) globs['WRANGLE'] = '{0}/vex_wrangles'.format(HIP) globs['PROXY'] = '{0}/proxy'.format(HIP) globs['MCACHE'] = '{0}/alembic'.format(HIP) globs['RCPATH'] = '{0}/render'.format(HIP) globs['REFPATH'] = '{0}/references'.format(HIP) globs['_EXPORT'] = '{0}/_Export'.format(HIP) # -------------- set houdini vaiables -------------- for key, val in globs.iteritems(): hou.hscript('set -g {0}={1}'.format(key, val)) hou.hscript('unitlength 0.1') import workCal reload(workCal) workCal.writeVisit(scenes=1)
def debug_refresh(node): try: node.node('debug/MESH').parm('reload').pressButton() hou.hscript("texcache -c") except: return