def go(): global rollback_window global src global asset_name nodes = hou.selectedNodes() project = Project() if len(nodes) == 1: asset = nodes[0] src = asset.type().definition().libraryFilePath() asset_name = os.path.basename(src) index = asset_name.find("_assembly") if index > 0: base_name = asset_name[:index] body = project.get_body(base_name) element = body.get_element(Department.ASSEMBLY) rollback_window = RollbackWindow(element, hou.ui.mainQtWindow()) rollback_window.finished.connect(rollback_hda) else: scene_name = hou.hipFile.name() shot = os.path.basename(scene_name) index = shot.find("_lighting") if index > 0: base_name = shot[:index] print base_name body = project.get_body(base_name) element = body.get_element(Department.LIGHTING) rollback_window = RollbackWindow(element, hou.ui.mainQtWindow()) rollback_window.finished.connect(rollback_shot)
def get_link(element=None, dept=None): if element is None: filePath = pm.sceneName() fileDir = os.path.dirname(filePath) proj = Project() checkout = proj.get_checkout(fileDir) # Make sure we have access to element data for this asset if checkout is None: message_gui.error( "Nothing is checked out.", "You must check out a model in order to see it's SketchFab link." ) return None else: body_name = checkout.get_body_name() dept_name = checkout.get_department_name() elem_name = checkout.get_element_name() body = proj.get_body(body_name) element = body.get_element(dept_name, name=elem_name) #Get the element from the right Department if dept is not None and not element.get_department() == dept: print 'We are overwriting the', element.get_department(), 'with', dept body = proj.get_body(element.get_parent()) element = body.get_element(dept) if element is None: message_gui.error("Nothing is checked out.", "There is no element associated with this asset.") return proj = Project() body_name = element.get_parent() body = proj.get_body(body_name) asset_file_path = element.get_dir() uid_file_path = '{0}/{1}.json'.format(asset_file_path, body_name) if not os.path.exists(uid_file_path): message_gui.error( "No SketchFab link was found.", "Either nothing was exported to SketchFab, or something went wrong during export." ) return model_uid = '' try: with open(uid_file_path) as uid_file: uid_file_data = json.load(uid_file) model_uid = uid_file_data['uid'] except ValueError: message_gui.error("The SketchFab link is broken :(", "You'll need to talk to pipeline about this.") return global SKETCHFAB_MODEL_URL model_url = SKETCHFAB_MODEL_URL + model_uid message_gui.input('Link:', 'SketchFab Link', model_url)
def rollback_asset_go(node=None): global rollback_window global asset_name global src if node is None: nodes = hou.selectedNodes() if len(nodes) == 1: node = nodes[0] elif len(nodes) > 1: message_gui.error('Please select only one node to rollback') return elif len(nodes) < 1: message_gui.error('Please select a node to rollback') return project = Project() src = node.type().definition().libraryFilePath() asset_name = os.path.basename(src) base_name = node.type().name() print base_name index = asset_name.find('_assembly') base_name = base_name.replace('_main1', '') print base_name #if index > 0: # base_name = asset_name[:index] ## message_gui.error('There was a problem finding the asset') # return #print '--------' #print base_name body = None element = None if node.name() in Department.ASSET_DEPTS: base_name = base_name.replace('_' + str(node.name()), '') body = project.get_body(base_name) element = body.get_element(str(node.name())) else: body = project.get_body(base_name.replace('_main', '')) element = body.get_element(Department.ASSEMBLY) rollback_window = RollbackWindow(element, hou.ui.mainQtWindow()) rollback_window.finished.connect(rollback_hda)
def publish_hda(publishWindow, selectedHDA, src): project = Project() environment = Environment() if publishWindow.published: user = publishWindow.user comment = publishWindow.comment hdaName = selectedHDA.type().name() department = publishWindow.elementName # TODO: UGLY HOTFIX FOR OLD ASSEMBLY & TOOL ASSETS asset_name = hdaName.replace("_" + department, "") if department not in [Department.ASSEMBLY, Department.HDA] else hdaName.replace("_main", "") body = project.get_body(asset_name) if body is None: message_gui.error("Asset not found in pipe.") return if os.path.exists(src): try: #save node definition this is the same as the Save Node Type menu option. Just to make sure I remember how this works - We are getting the definition of the selected hda and calling the function on it passing in the selected hda. We are not calling the funciton on the selected hda. selectedHDA.type().definition().updateFromNode(selectedHDA) except hou.OperationFailed, e: message_gui.error('There was a problem publishing the HDA to the pipeline.\n', details=str(e)) return try: selectedHDA.matchCurrentDefinition() except hou.OperationFailed, e: message_gui.warning('There was a problem while trying to match the current definition. It\'s not a critical problem but it is a little troubling. Take a look at it and see if you can resolve the problem. Rest assured that the publish did work though', details=str(e))
def rollback_shot_go(): scene_name = hou.hipFile.name() shot = os.path.basename(scene_name) index = shot.find('_lighting') if index > 0: base_name = shot[:index] department = Department.LIGHTING else: index = shot.find('_fx') if index > 0: base_name = shot[:index] department = Department.FX else: # If there is no shot opened then we allow the user to select one from all of the comps. global rollback_selection_window rollback_selection_window = SelectionWindow( hou.ui.mainQtWindow(), dept_list=[Department.LIGHTING, Department.FX]) rollback_selection_window.finished.connect(post_selection) return print base_name project = Project() body = project.get_body(base_name) element = body.get_element(department) global rollback_window rollback_window = RollbackWindow(element, hou.ui.mainQtWindow()) rollback_window.finished.connect(rollback_shot)
def rollback_tool_go(node=None): global rollback_window global asset_name global src if node is None: nodes = hou.selectedNodes() if len(nodes) == 1: node = nodes[0] elif len(nodes) > 1: message_gui.error('Please select only one node to rollback') return elif len(nodes) < 1: message_gui.error('Please select a node to rollback') return project = Project() src = node.type().definition().libraryFilePath() asset_name = os.path.basename(src) index = asset_name.find('_hda') if index > 0: base_name = asset_name[:index] else: message_gui.error('There was a problem finding the tool') return body = project.get_body(base_name) element = body.get_element(Department.HDA) rollback_window = RollbackWindow(element, hou.ui.mainQtWindow()) rollback_window.finished.connect(rollback_hda)
def json_audit(): project = Project() environment = Environment() asset_dir = project.get_assets_dir() failed_str = "" for i, asset in enumerate(project.list_assets(AssetType.PROP)): try: asset_obj = project.get_body(asset) element_obj = asset_obj.get_element(Department.MODEL, force_create=True) element_path = element_obj.checkout( environment.get_current_username()) checkout.non_gui_open(element_path, asset) json_exporter_non_gui.exportProp(asset_obj) except Exception, err: error_str = "" error_str += "\nError exporting JSON for {0}".format(asset) error_str += "\n" + traceback.format_exc() print error_str failed_str += error_str continue
def confirmWritePropReference(body=None): filePath = pm.sceneName() fileDir = os.path.dirname(filePath) project = Project() if not body: checkout = project.get_checkout(fileDir) bodyName = checkout.get_body_name() body = project.get_body(bodyName) if body.is_asset() and body.get_type() == AssetType.PROP: element = body.get_element(Department.MODEL) filePath = os.path.join(project.get_assets_dir(), element.get_cache_dir()) assemblies = pm.ls(assemblies=True) pm.select(pm.listCameras(), replace=True) cameras = pm.selected() pm.select([]) non_cameras = [ assembly for assembly in assemblies if assembly not in cameras ] exportPropJSON(filePath, non_cameras[0], isReference=False, name=body.get_name()) showSuccessPopup()
def go(): try: scene_name = mari.projects.current().name() except: message_gui.error( "You need to open the project that you would like to rollback.") return shot = os.path.basename(scene_name) index = shot.find("_texture") if index > 0: base_name = shot[:index] print base_name else: message_gui.error( "We couldn't figure out what asset you are working on.") return project = Project() body = project.get_body(base_name) element = body.get_element(Department.TEXTURE) global rollback_window parent = QtWidgets.QApplication.activeWindow() rollback_window = RollbackWindow(element, parent) rollback_window.finished.connect(post_rollback)
def go(element=None, dept=None): pm.loadPlugin('fbxmaya.so') if not pm.sceneName() == '': pm.saveFile(force=True) if element is None: filePath = pm.sceneName() fileDir = os.path.dirname(filePath) proj = Project() checkout = proj.get_checkout(fileDir) # Make sure we have access to element data for this asset if checkout is None: message_gui.error( "Nothing is checked out.", "You must check out a model in order to publish it to SketchFab." ) return None else: body_name = checkout.get_body_name() dept_name = checkout.get_department_name() elem_name = checkout.get_element_name() body = proj.get_body(body_name) element = body.get_element(dept_name, name=elem_name) #Get the element from the right Department if dept is not None and not element.get_department() == dept: print 'We are overwriting the', element.get_department(), 'with', dept body = proj.get_body(element.get_parent()) element = body.get_element(dept) if element is None: print "Nothing is selected." return if not element.get_department() == Department.MODEL: message_gui.error( "We can only publish models to sketchFab (no rigs).", "Please check out a model (sets included) if you wish to publish to SketchFab." ) else: export(element)
def export(element, selection=None, startFrame=None, endFrame=None): proj = Project() bodyName = element.get_parent() body = proj.get_body(bodyName) abcFilePath = element.get_cache_dir() #TODO we don't want to put them into the element cache right away. We want to put them in a seperate place and then copy them over later. if startFrame is None: startFrame = pm.playbackOptions(q=True, animationStartTime=True) if endFrame is None: endFrame = pm.playbackOptions(q=True, animationEndTime=True) if body.is_shot(): startFrame -= 5 endFrame += 5 files = exportReferences(abcFilePath, tag='BYU_Alembic_Export_Flag', selectionMode=True, startFrame=startFrame, endFrame=endFrame) result = message_gui.yes_or_no( 'Are there any crowds that need to be exported?') if result: exportCrowd(abcFilePath, 'BYU_Crowd_Agent_Flag', tag='BYU_Alembic_Export_Flag', startFrame=startFrame, endFrame=endFrame) elif body.is_asset(): if body.get_type() == AssetType.SET: files = exportReferences(abcFilePath) else: files = exportAll(abcFilePath, element=element) elif body.is_crowd_cycle(): files = exportAll(abcFilePath, tag='BYU_Alembic_Export_Flag', startFrame=startFrame, endFrame=endFrame, element=element) if not files: #Maybe this is a bad distinction but None is if it was canceled or something and empty is if it went but there weren't any alembics if files is None: return message_gui.error('No alembics were exported') return for abcFile in files: os.system('chmod 774 ' + abcFile) #TODO install the geometry print 'These are the files that we are returning', files return files
def go(element=None, dept=None, selection=None, startFrame=None, endFrame=None): pm.loadPlugin('AbcExport') if not pm.sceneName() == '': pm.saveFile(force=True) if element is None: filePath = pm.sceneName() fileDir = os.path.dirname(filePath) proj = Project() checkout = proj.get_checkout(fileDir) if checkout is None: parent = QtWidgets.QApplication.activeWindow() element = selection_gui.getSelectedElement(parent) if element is None: return None else: bodyName = checkout.get_body_name() deptName = checkout.get_department_name() elemName = checkout.get_element_name() body = proj.get_body(bodyName) element = body.get_element(deptName, name=elemName) #Get the element from the right Department if dept is not None and not element.get_department() == dept: print 'We are overwriting the', element.get_department(), 'with', dept body = proj.get_body(element.get_parent()) element = body.get_element(dept) return export(element, selection=selection, startFrame=startFrame, endFrame=endFrame)
def audit(): project = Project() environment = Environment() asset_dir = project.get_assets_dir() for i, asset in enumerate(project.list_assets(AssetType.PROP)): asset_obj = project.get_body(asset) element_obj = asset_obj.get_element(Department.MODEL, force_create=True) element_path = element_obj.checkout(environment.get_current_username()) #cmds.file(rename='/tmp/lol'+str(i)+'.mb') #cmds.file(save=True) checkout.non_gui_open(element_path, asset) print 'Done'
def non_gui_publish_hda(hda=None,comment='N/A'): if hda is None: print ('Error with asset') project = Project() environment = Environment() user = environment.get_current_username() hdaName = hda.type().name() department=None if str(hda) not in Department.ALL: print 'v1 asset' department=Department.ASSEMBLY else: department=str(hda) asset_name = hdaName.replace("_" + department, "") if department not in [Department.ASSEMBLY, Department.HDA] else hdaName.replace("_main", "") body = project.get_body(asset_name) if body is None: message_gui.error('No asset in pipe') return #TODO: publish tools if body.is_tool(): print (asset_name+' is tool') return department=Department.HDA hda_src = hda.type().definition().libraryFilePath() print hda_src element = body.get_element(department, Element.DEFAULT_NAME,force_create=True) try: hda.type().definition().updateFromNode(hda) except hou.OperationFailed, e: message_gui.error('There was a problem publishing the HDA to the pipeline.\n', details=str(e)) return
def go(body=None, type=AssetType.SET): if not body: parent = publish.maya_main_window() filePath = pm.sceneName() fileDir = os.path.dirname(filePath) project = Project() checkout = project.get_checkout(fileDir) if not checkout: filePath = Environment().get_user_workspace() filePath = os.path.join(filePath, 'untitled.mb') filePath = pipeline_io.version_file(filePath) global maya_publish_dialog selection_list = [] if type == "shot": selection_list = Project().list_shots() elif type == AssetType.PROP: selection_list = [] for asset in Project().list_assets(): body = project.get_body(asset) if body.get_type() != AssetType.PROP: continue selection_list.append(asset) elif type == AssetType.SET: selection_list = Project().list_sets() else: print("Didn't export JSON, because it probably is a character.") return maya_publish_dialog = SelectFromList(parent=maya_main_window()) maya_publish_dialog.setWindowTitle("Select shot" if type == "shot" else "Select prop" if type == AssetType.PROP else "Select set") maya_publish_dialog.setList(selection_list) maya_publish_dialog.filePath = filePath maya_publish_dialog.selected.connect(publish_submitted) maya_publish_dialog.show() else: if type == "shot": confirmWriteShotReferences(body) elif type == AssetType.PROP: confirmWritePropReference(body) elif type == AssetType.SET: confirmWriteSetReferences(body)
def go(): project = Project() filepath = cmds.file(q=True, sceneName=True) checkout = project.get_checkout(os.path.dirname(filepath)) if checkout is not None: body_name = checkout.get_body_name() body = project.get_body(body_name) if body.is_shot(): frame_range = body.get_frame_range() if frame_range > 0: print "set frame range to " + str(frame_range) cmds.playbackOptions(animationStartTime=1.0, animationEndTime=frame_range, minTime=1.0, maxTime=frame_range, framesPerSecond=24) else: print "shot has invalid frame range" else: print "not a shot" else: print "Unknown Shot, can't set frame range"
def confirmWriteShotReferences(body=None): #response = showConfirmationPopup() #if response == "Yes": filePath = pm.sceneName() filDir = os.path.dirname(filePath) proj = Project() if not body: checkout = proj.get_checkout(fileDir) bodyName = checkout.get_body_name() body = proj.get_body(bodyName) if body.is_shot(): print("SHOT OK") element = body.get_element(Department.ANIM) refsFilePath = os.path.join(Project().get_assets_dir(), element.get_cache_dir()) export_shot(refsFilePath) else: print("NOT A SHOT") showFailurePopup('No set found in current scene.')
def writeXML(assetName='None', context='OBJ'): project = Project() asset_body = project.get_body(assetName) icon = os.path.join('$JOB', 'byu-pipeline-tools', 'assets', 'images', 'icons', 'tool-icons', '2.png') if not asset_body.is_asset(): print('error me this') raise Exception('Failed to generate XML for: ' + assetName + ' \n Object is not an Asset') global baseXML xml = Template(baseXML).substitute(NAME=assetName, LABEL=assetName.replace('_', ' ').title(), ICON=icon, CONTEXT=context) try: path = os.path.join(project.get_assets_dir(), assetName) path = os.path.join(path, assetName + '.shelf') file = open(path, 'w') file.write(xml) file.close() if not os.path.exists(project.get_tabs_dir()): os.makedirs(project.get_tabs_dir()) sym = os.path.join(project.get_tabs_dir(), assetName + '.shelf') if os.path.exists(sym): os.unlink(sym) os.link(path, sym) except Exception as e: print e raise Exception('Failed to generate XML for: ' + assetName)
def export(element): proj = Project() body_name = element.get_parent() body = proj.get_body(body_name) asset_file_path = element.get_dir() uid_file_path = '{0}/{1}.json'.format(asset_file_path, body_name) print uid_file_path republish = os.path.exists(uid_file_path) fbx_file = prepare_files(body_name) data = None model_uid = '' if republish: with open(uid_file_path) as uid_file: uid_file_data = json.load(uid_file) model_uid = uid_file_data['uid'] data = republish_existing_asset(body.get_name(), body.get_description(), model_uid) else: data = publish_new_asset(body.get_name(), body.get_description()) f = open(fbx_file, 'rb') files = {'modelFile': f} try: model_uid = upload_to_sketchfab(data, files, republish, model_uid) #poll_processing_status(model_uid) finally: f.close() if not model_uid is None and len(model_uid) > 0 and not republish: uid_data = {'uid': model_uid} with open(uid_file_path, 'w') as outfile: json.dump(uid_data, outfile)
def go(): parent = QtGui.QApplication.activeWindow() filepath = nuke.toNode("root").name() shot = os.path.basename(filepath) index = shot.find("_comp") if index > 0: base_name = shot[:index] print base_name else: # If there is no composition opened then we allow the user to select one from all of the comps. global rollback_selection_window rollback_selection_window = SelectionWindow( parent, dept_list=[Department.COMP]) rollback_selection_window.finished.connect(post_selection) return project = Project() body = project.get_body(base_name) element = body.get_element(Department.COMP) # nuke.scriptClose() global rollback_window rollback_window = RollbackWindow(element, parent) rollback_window.finished.connect(post_rollback)
def assemble_set(project, environment, assembly, asset, checkout_file): set_hda = create_hda(asset, assembly, project, environment, checkout_file) print 'This is a set' print('----------') model = asset.get_element(Department.MODEL) # Get all of the static geo model_cache = model.get_cache_dir() model_cache = model_cache.replace(project.get_project_dir(), '$JOB') geo_files = [x for x in os.listdir(model.get_cache_dir()) if not os.path.isdir(x)] geo_files = clean_file_list(geo_files, '.abc') # Set up the set parameters # Create a folder for the set parameters set_folder = hou.FolderParmTemplate('set_options', 'Set Options', folder_type=hou.folderType.Tabs, default_value=0, ends_tab_group=False) auto_archive = hou.properties.parmTemplate(get_latest_prman(),"ri_auto_archive") auto_archive.setDefaultValue(("exist",)) set_folder.addParmTemplate(auto_archive) set_folder.addParmTemplate(create_set_menu(hidden=True, value=asset.get_name())) set_folder.addParmTemplate(create_shot_menu()) used_hdas = set() for geo_file in geo_files: geo_file_path = os.path.join(model_cache, geo_file) name = ''.join(geo_file.split('.')[:-1]) #print 'The name of the alembic file is ', name # find the alembic version elementName = '_main' index = name.find(elementName) versionNum = name[index + len(elementName):] #print 'This is the versionNum ', versionNum # TODO : what if it is a rig? I am begninng to wonder if maybe it will always be the model becuase in the rig file it is referencing the model. index = name.find('_model') if(index < 0): index = name.find('_rig') if(index < 0): print 'We couldn\'t find either a rig or a model for this asset. That means something went wrong or I need to rethink this tool.' asset_name = name[:index] #check if HDA is set to prevent nested set HDAS project=Project() body = project.get_body(asset_name) print asset_name if body is not None: if body.get_type() == AssetType.SET: continue else: print ('No body exists for: ' + asset_name) continue #print asset_name asset_version = str(asset_name) + str(versionNum) if(asset_version in used_hdas): print used_hdas print 'But I think is okay if it is in used_hdas because we have decided that it\'s cool to have multibples' #TODO get rid of used_hdas if we don't need it anymore now that we are allowing duplication of assets continue try: hda = set_hda.createNode(asset_name + '_main') except: message_gui.error('There is no asset named ' + str(asset_name) + '. You may need to assemble it first.') hda.destroy() return used_hdas.add(asset_version) # set the alembic version number if versionNum != '': try: #print 'This is versionNum before the change ', versionNum versionNum = int(versionNum) #print 'This is versionNum after the change ', versionNum hda.parm('abcversion').set(int(versionNum)) except Exception as err: errorMessage = 'There was an error assigning the version number. It may be because the asset needs to be reassembled. Check that the ' + str(asset_name) + ' node has the version slider. If not reassemble it and try again.\n' message_gui.error(errorMessage, details=str(err)) #finish the rest of the setup label_text = asset_version.replace('_', ' ').title() # Using the column label instead of the regular label lets us put longer names without them getting truncated. The problem is that its not left justified like I would want but its going to have to do for now. It is really quite a bit less than ideal but it will still comunicate the needed info so here we go. columnLabel = (label_text,) #print columnLabel geo_label = hou.LabelParmTemplate(asset_version, '', column_labels=columnLabel) hide_toggle_name = 'hide_' + asset_version hide_toggle = hou.ToggleParmTemplate(hide_toggle_name, 'Hide') animate_toggle_name = 'animate_' + asset_version animate_toggle = hou.ToggleParmTemplate(animate_toggle_name, 'Animate') animate_toggle_to_int_name = 'animate_toggle_to_int_' + asset_version animate_toggle_to_int = hou.IntParmTemplate(animate_toggle_to_int_name, 'Toggle To Int', 1, is_hidden=True, default_expression=('ch("' + animate_toggle_name + '")',)) set_folder.addParmTemplate(geo_label) set_folder.addParmTemplate(hide_toggle) set_folder.addParmTemplate(animate_toggle) set_folder.addParmTemplate(animate_toggle_to_int) try: hda.parm('hide').setExpression('ch("../' + hide_toggle_name + '")') hda.parm('shot').setExpression('chs("../shot")') hda.parm('set').setExpression('chs("../set")') hda.parm('source').setExpression('chs("../' + animate_toggle_to_int_name + '")') except AttributeError, e: message_gui.error("There was an error adding " + str(asset_name) + " to the set. Please make sure that the node exists and has all of the necessary parameters (hide, shot, set, source) and try again. Contact the pipeline team if you need help. We will continue assembling so you can see the output, but you will need to assemble this set again.", details=str(e)) except Exception, e: message_gui.error('There was a problem with this node: ' + str(asset_name), details=str(e))