def set_project(kwargs): node = kwargs['node'] project_name = node.evalParm('proj') # project_name = kwargs['script_value'] node.parm('scene').set('') unset_all_scene_vars() data = read_json() if project_name == '-': hou.unsetenv('PROJECT') hou.unsetenv('CODE') hou.unsetenv('PROJ_FPS') hou.setFps(24) hou.unsetenv('PROJECT_PATH') hou.unsetenv('SCENES_PATH') hou.unsetenv('HDA_PATH') hou.unsetenv('SCRIPTS_PATH') node.cook(True) return try: project_data = data[project_name] except KeyError: util.error('Project Data not found') return hou.putenv('PROJECT', project_name) hou.putenv('CODE', project_data['CODE']) fps = project_data['FPS'] hou.putenv('PROJ_FPS', str(fps)) hou.setFps(fps) project_path = project_data['PATH'] hou.putenv('PROJECT_PATH', project_data['PATH']) create_folder_and_var('SCENES_PATH', util.fix_path(os.path.join(project_path, 'scenes'))) hda_path = util.fix_path(os.path.join(project_path, 'hda')) create_folder_and_var('HDA_PATH', hda_path) scripts_path = util.fix_path(os.path.join(project_path, 'scripts')) create_folder_and_var('SCRIPTS_PATH', scripts_path) hda_paths = [hda_path, ] scan_path = hou.getenv('HOUDINI_OTLSCAN_PATH') if scan_path: hda_paths += scan_path.split(';') hda_paths = list(set(hda_paths)) hou.putenv('HOUDINI_OTLSCAN_PATH', ';'.join(hda_paths)) hou.hda.reloadAllFiles() sys.path.append(scripts_path) node.cook(True)
def set_scene(kwargs): node = kwargs['node'] scene_name = node.evalParm('scene') # If null scene > unset all if scene_name == '': unset_all_scene_vars() node.cook(True) return # If no PROJECT_PATH var project_path = hou.getenv('PROJECT_PATH') if not project_path or not os.access(project_path, os.F_OK): util.error('Project path is invalid') return # If no SCENES_PATH var scenes_path = hou.getenv('SCENES_PATH') if not scenes_path or not os.access(scenes_path, os.F_OK): util.error('Scenes path is invalid') return # If SCENES_PATH var but no folder if not os.access(scenes_path, os.F_OK): os.makedirs(scenes_path) scene_path = util.fix_path(os.path.join(scenes_path, scene_name)) if not os.access(scene_path, os.F_OK): message = 'Scene folder "{0}" does not exist\n'\ 'Create this folder now?'.format(scene_name) choice = hou.ui.displayMessage(message, severity=hou.severityType.ImportantMessage, buttons=('Yes', 'No')) if choice == 0: os.makedirs(scene_path) else: unset_all_scene_vars() node.cook(True) return hou.putenv('SCENE', scene_name) hou.putenv('SCENE_PATH', scene_path) create_folder_and_var('SAVE_PATH', os.path.join(scene_path, 'working_files')) output_path = os.path.join(scene_path, 'output') create_folder_and_var('OUTPUT_PATH', output_path) create_folder_and_var('CACHE_PATH', os.path.join(output_path, 'cache')) create_folder_and_var('RENDER_PATH', os.path.join(output_path, 'render')) node.cook(True)
def watchlist_action(kwargs): node = kwargs['node'] parent_num = kwargs['script_multiparm_index2'] parent_parm = node.parm('watch_node_{0}'.format(parent_num)) parent_node = parent_parm.evalAsNode() if not parent_node: util.error('Invalid node selected') return parm_list = [] for p in parent_node.parms(): template = p.parmTemplate() parm_type = template.type() if parm_type == hou.parmTemplateType.Folder or parm_type == hou.parmTemplateType.FolderSet: continue parm_list.append(p) tree_list = [] for p in parm_list: hierarchy = list(p.containingFolders()) hierarchy.append('{0} ({1})'.format(p.parmTemplate().label(), p.name())) tree_list.append('/'.join(hierarchy)) choice = hou.ui.selectFromTree(tree_list, exclusive=True, message='Select a parameter to watch', title='Watchlist Select', clear_on_cancel=True) if len(choice) > 0: idx = tree_list.index(choice[0]) parm = parm_list[idx] val_parm = kwargs['parmtuple'][0] name_parm = node.parm(val_parm.name()[:-4]) name_parm.set(parm.name()) return
def restore(kwargs): node = kwargs['node'] scene_data = None for n in hou.node('/obj').children(): if n.type().nameComponents()[2] == 'scene_data': scene_data = n break if not scene_data: util.error( 'Scene Data node not found. Scene cannot be correctly restored') return if os.path.dirname(hou.hipFile.path()) == hou.getenv('SAVE_PATH'): message = 'Current .hip already seems to be saved to \"working_files\" directory\n'\ 'Are you sure you want to perform this operation?' choice = hou.ui.displayMessage(message, buttons=('Yes', 'No'), severity=hou.severityType.Warning) if choice == 1: return try: metadata = node.node('READ_METADATA').geometry().attribValue( 'hipfile_source') except hou.OperationFailed: util.error('Unable to find source file in metadata') return regex = r'(?P<scene>^\w+)-(?P<task>\w+)-(?P<ver>v\d{3,})(-(?P<desc>\w+))?-(?P<user>\w+)\.(?P<ext>hip\w*$)' match = re.match(regex, metadata) if not match: util.error('Source does not align with correct naming convertion. \n' 'Unable to restore file correctly') return task = match.group('task') if not task or task == '': util.error( 'Unable to find task name from metadata.\n' 'Reverting to "restore" task name', severity=hou.severityType.Warning) task = 'restore' desc = 'restore' save_scene.save_scene(None, task, desc)
def watchlist_restore_single(kwargs): node = kwargs['node'] read_node = node.node('READ_METADATA') geo = read_node.geometry() watchlist = geo.attribValue('watchlist') watchlist_dict = json.loads(watchlist) parent_num = kwargs['script_multiparm_index2'] parent_parm = node.parm('read_watch_node_{0}'.format(parent_num)) parent_node = parent_parm.evalAsNode() if not parent_node: util.error('Node to restore to [{0}] does not exist'.format( parent_parm.evalAsString())) return parm_num = kwargs['script_multiparm_index'] parm = node.parm('read_watch_parm_{0}_{1}'.format(parent_num, parm_num)) parm_name = parm.eval() parm_to_restore = parent_node.parm(parm_name) if not parm_to_restore: util.error('Parm to restore [{0}/{1}] does not exist'.format( parent_node.path(), parm_name)) return vals = watchlist_dict[parent_node.path()][parm_name] if vals[0] == '<< Animated Parameter >>': util.error( 'This parm [{0}] is an Animated Parameter and cannot be restored this way' .format(parm_name), severity=hou.severityType.Warning) return try: parm_to_restore.set(vals[0]) print('Parm [{0}/{1}] restored to [{2}]'.format( parent_node.path(), parm_name, vals[1])) except TypeError: parm_to_restore.set(vals[1]) print('Parm [{0}/{1}] restored to [{2}]'.format( parent_node.path(), parm_name, vals[1])) return
def error_report(message, severity=hou.severityType.Error): util.error(message, severity=severity) generateReport(False, error=message)
def save_scene(kwargs=None, task=None, desc=None): if kwargs: ctrl = kwargs['ctrlclick'] else: ctrl = False # Find scene_data node scene_data = None scene_data_nodes = [] for n in hou.node('/obj').children(): if n.type().nameComponents()[2].startswith('scene_data'): scene_data_nodes.append(n) if len(scene_data_nodes) > 1: util.error('Multiple SCENE DATA nodes found\nAborting Operation') elif len(scene_data_nodes) == 1: scene_data = scene_data_nodes[0] else: util.error( 'SCENE DATA node not found\nPlease create one and select a scene before saving' ) return # Gather variables save_path = hou.getenv('SAVE_PATH') scene = hou.getenv('SCENE') if not save_path or not scene: util.error( 'Local variables not defined\nPlease use SCENE DATA node to set these correctly' ) return # Set task and desc from curr scene or initialize curr_name = hou.hipFile.basename() regex = r'^(?P<scene>\w+)-(?P<task>\w+)-(?P<full_ver>v(?P<ver>\d{3,}))(-(?P<desc>\w+))?-(?P<user>\w+)' \ r'(\.(?P<ext>\w+))$' match = re.match(regex, curr_name, flags=re.IGNORECASE) if match: if not task: task = match.group('task') if not desc: desc = match.group('desc') if not task: task = '' if not desc: desc = '' ask_input = True if ctrl and task != '': ask_input = False # Input Task and Description if ask_input: repeat = True while repeat: repeat = False user_input = hou.ui.readMultiInput( 'Select Task and Description', ('Task', 'Description (optional'), buttons=('OK', 'Cancel'), initial_contents=(task, desc)) if user_input[0] == 1: return task = user_input[1][0] desc = user_input[1][1] if task == '': util.error('Task cannot be left blank', hou.severityType.Warning) repeat = True continue # Set version regex = '(?P<scene>{scene})-(?P<task>{task})-v(?P<ver_num>\\d{{3,}})'.format( scene=scene, task=task) ver_nums = [] for f in os.listdir(save_path): if not os.path.isdir(f): match = re.match(regex, f, flags=re.IGNORECASE) if match: ver_nums.append(int(match.group('ver_num'))) if len(ver_nums) > 0: high_ver = sorted(ver_nums)[-1] ver = 'v{0:>03}'.format(high_ver + 1) else: ver = 'v001' # Set User user = hou.getenv('USER').lower() components = [scene, task, ver, desc, user] for i, c in enumerate(components): if c and c != '': components[i] = clean_name(c) else: del components[i] # Set extension lic_dict = { 'Commercial': 'hip', 'Indie': 'hiplc', 'Apprentice': 'hipnc', 'ApprenticeHD': 'hipnc', 'Education': 'hipnc' } lic = hou.licenseCategory().name() ext = lic_dict[lic] # Build Filename name = '-'.join(components) filename = '{path}/{name}.{ext}'.format(path=save_path, name=name, ext=ext) # Save hou.hipFile.save(filename)
def add_proj(): data = read_json() # Init _proj_name = None path = None path_name = None path_code = None path_fps = None # Select Proejct Path repeat = True while repeat: repeat = False _path = hou.ui.selectFile(title='Select Project Directory', file_type=hou.fileType.Directory) path = os.path.dirname(_path) if path == '': return for k, v in data.items(): if util.fix_path(path) == util.fix_path(v['PATH']): util.error( 'Project path is already used by another project {0}\nPlease select a different path' .format(k)) repeat = True break if repeat: continue _proj_name = os.path.split(path)[-1] # Select Project Name, Code and FPS repeat = True while repeat: repeat = False inputs = hou.ui.readMultiInput(message='Enter Project Data', input_labels=('Project Name', 'Project Code', 'FPS'), buttons=('OK', 'Cancel'), initial_contents=(_proj_name, '', '24')) if inputs[0] == 1: return proj_name = inputs[1][0] proj_code = inputs[1][1] proj_fps = inputs[1][2] if proj_name == '' or proj_code == '' or proj_fps == '': util.error('Please fill in all fields') repeat = True continue try: proj_fps = int(proj_fps) except ValueError: util.error( 'FPS not set to a number. \n Please enter a whole number') repeat = True continue for k, v in data.items(): if proj_name == k: util.error( 'Project name is already in use\nPlease select a different name' ) repeat = True break if proj_code == v['CODE']: util.error( 'Project code is already in use\nPlease select a different code' ) repeat = True break if repeat: continue if proj_name and proj_code and proj_fps: proj_data = {'CODE': proj_code, 'PATH': path, 'FPS': proj_fps} data[proj_name] = proj_data if data: with open(proj_list, 'w') as f: json.dump(data, f, sort_keys=True, indent=4)