def create_set_menu(hideWhen=None, callback_script=None, hidden=False, value=None): item_gen_script=''' from byuam.project import Project project = Project() set_list = list() sets = project.list_sets() for set in sets: set_list.append(set) set_list.append(set.replace('_', ' ').title()) return set_list ''' project = Project() if(value == None): if len(project.list_sets()) < 1: message_gui.error('There are currently no sets in created in the film. Because of how this node works you are going to have to create at least one set before assembling anything.') raise('No sets in the project') default_set = (str(project.list_sets()[0]),) else: default_set = (value,) #print default_set set_menu = hou.StringParmTemplate('set', 'Set', 1, item_generator_script=item_gen_script, is_hidden=hidden, menu_type=hou.menuType.Normal, script_callback=callback_script, script_callback_language=hou.scriptLanguage.Python, default_value=default_set) #print set_menu.defaultValue() if hideWhen is not None: set_menu.setConditional( hou.parmCondType.HideWhen, '{ ' + hideWhen + ' }') return set_menu
def go(scope=ALL): if mari.projects.current() is None: message_gui.error( 'You need to have a project open in order to export textures.') return None global mari_selection_dialog texture = get_texture() if texture is None: parent = QtWidgets.QApplication.activeWindow() mari_selection_dialog = SelectionWindow(parent, [Department.TEXTURE]) if scope is SELECTED_GEO: mari_selection_dialog.finished.connect(export_selected_geo_to_tex) elif scope is SELECTED_CHANNEL: mari_selection_dialog.finished.connect( export_selected_channel_to_tex) else: mari_selection_dialog.finished.connect(export_all_to_tex) else: if scope is SELECTED_GEO: export_selected_geo_to_tex(texture) elif scope is SELECTED_CHANNEL: export_selected_channel_to_tex(texture) else: export_all_to_tex(texture)
def getClusterListForVert(vert, clusters=None): result = [] if clusters is None: clusters = pm.ls(type="cluster") clusterCnt = len(clusters) for index, c in enumerate(clusters): objectSets = c.listConnections(type="objectSet") if not len(objectSets) == 1: results = list() for objSet in objectSets: if "cluster" in objSet.name(): results.append(objSet) if not len(results) == 1: message_gui.error( "There is more than one object set tied to this cluster. That is something I didn't expect. Please let me know about it. Let's keep going though and see what happens. The list of object sets looks like this: " + str(results)) continue else: objectSet = results[0] else: objectSet = objectSets[0] if vert in objectSet[0]: result.append(c) print str(index + 1) + " of " + str(clusterCnt) + " clusters processed." print "Len of result: ", len(result) print "Type of clusters: ", type(clusters[0]) print "Type of result items: ", type(result[0]) return result
def make_xml(): if len(hou.selectedNodes()) > 0: xml = [] errors = [] error = False for node in hou.selectedNodes(): try: name = node.parm('data').evalAsJSONMap()['asset_name'] byu_xml.writeXML(name) xml.append(name) except Exception as e: error = True errors.append(e.args) print e.args if error == True: message_gui.error( 'There was an issue generating xml for one of the selected nodes', str(errors)) message_gui.message( 'Finished', 'Successfully generated XML for the following: ' + str(xml)) else: global WINDOW WINDOW = CheckoutWindow(hou.ui.mainQtWindow(), [Department.ASSEMBLY]) WINDOW.finished.connect(xml_callBack)
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 non_gui_publish_go(selectedHDA=None,comment=None): if selectedHDA != None: non_gui_publish_hda(selectedHDA,comment) else: message_gui.error('Please select a single node') return
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 farmCustomRender(): print 'Start Tractor Render' try: tractor.go(getEngineParts()['merge'].inputAncestors()) except hou.OperationFailed, e: message_gui.error( 'There was an error completeing the render. Check the ris nodes in the render engine node for details.', details=str(e))
def post_assemble(): mari.projects.close() asset_name = mari_assemble_dialog.result print asset_name if asset_name is None: return # Set up the project and environment project = Project() environment = Environment() # get the username and asset username = project.get_current_username() asset = project.get_asset(asset_name) # get the texture element and check it out texture = asset.get_element(Department.TEXTURE) checkout_file = texture.checkout(username) # Get the path to the directory with all of the alembics model = asset.get_element(Department.MODEL) cache = model.get_cache_dir() geo_files = [ x for x in os.listdir(model.get_cache_dir()) if not os.path.isdir(x) ] # Remove anything that is not an alemibic file for file_path in list(geo_files): if (not str(file_path).lower().endswith('.abc')): geo_files.remove(file_path) if len(geo_files) > 1: result = message_gui.light_error( 'There are multiple alembic files in ' + str(file_path) + ' and there should only be one.\nWould you like to continue anyways?\nIt might not work.' ) if not result: return elif len(geo_files) > 1: message_gui.error( 'There is not an alembic cache for this asset. Make sure that the model has been published in Maya and that the static alembic has been exported.' ) return geo_file_path = os.path.join(cache, geo_files[0]) mari.projects.create( texture.get_long_name(), geo_file_path, [], [], dict(), [ { '/': mari.geo.GEOMETRY_IMPORT_DONT_MERGE_CHILDREN }, ]) # At this point there should be no files left to add but if there are then the user was warned about it and we can go ahead and try to load those in. # This was from when we exported a bunch of alembics from Maya instead of just one. And since it shouldn't get called unless something goes wrong I figure it might be interesting to see what would happen if something goes wrong so we might as well leave it. for i in range(1, len(geo_files)): geo_file_path = os.path.join(cache, geo_files[i]) mari.geo.load(geo_file_path) print 'Loaded ' + geo_file_path
def gridmarketsRender(): if prepRender(openExr=True): print 'Start Gridmarkets Render' try: getEngineParts()['gridmarkets'].parm('submit_start').pressButton() except hou.OperationFailed, e: message_gui.error( 'There was an error completeing the render. Check the ris nodes in the render engine node for details.', details=str(e))
def localRender(): if prepRender(): print 'Start Local Render' try: getEngineParts()['merge'].render() except hou.OperationFailed, e: message_gui.error( 'There was an error completeing the render. Check the ris nodes in the render engine node for details.', details=str(e))
def createBodyHandler(self): try: name = str(self.textField.text()) name = name.replace(' ', '_') createBody(self.element, name) self.parent.accept() except EnvironmentError, e: message_gui.error( 'There is already an crowd cycle with that name.', details=e) print e self.parent.accept()
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 xml_callBack(): global WINDOW print WINDOW assetName = WINDOW.current_item print assetName try: byu_xml.writeXML(assetName) message_gui.message('Success, reload shelves to see asset') except Exception as e: print e.args message_gui.error('There was a problem', e.args)
def publish_submitted(value): body = Project().get_body(value) if body.is_asset(): if body.get_type() == AssetType.SET: confirmWriteSetReferences(body) elif body.get_type() == AssetType.PROP: confirmWritePropReference(body) else: print("No JSON exported because this is a character.") elif body.is_shot(): confirmWriteShotReferences(body) else: message_gui.error("Not a valid body.")
def create_hda_from_selection(nodes, department): if len(nodes) == 0: message_gui.error('Error with Selected Nodes') return else: errors = [] for node in nodes: try: assetName = node.parm('data').evalAsJSONMap()['asset_name'] assemble_v2.create_hda(assetName, department) except Exception as e: errors.append(e) if len(errors) > 0: message_gui.error('A problem occured', str(errors))
def checkout_hda_go(hda=None): global checkout_window project = Project() environment = Environment() if hda is None: nodes = hou.selectedNodes() if len(nodes) == 1: hda = nodes[0] elif len(nodes) > 1: message_gui.error('Only one node can be selected for checkout') return else: message_gui.error('You need to select an asset node to checkout') return if hda.type().definition() is not None: result = checkout_hda(hda, project, environment) if result is not None: print('checkout successful') #I think having the node unlock is visual que enough that the checkout was fine. Mostly it's annoying to have the window there. And we have a window that will let them know if it didn't work. #message_gui.info('Checkout Successful!', title='Success!') else: message_gui.error('Checkout Failed', title='Failure :()') else: message_gui.error('Node is not a digital asset') return
def getElementCacheDirectory(path, element=None): if element is None: proj = Project() checkout = proj.get_checkout(path) if checkout is None: message_gui.error( 'There was a problem exporting the alembic to the correct location. Checkout the asset again and try one more time.' ) return None body = proj.get_body(checkout.get_body_name()) element = body.get_element(checkout.get_department_name(), checkout.get_element_name()) return element.get_cache_dir()
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 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 go(): verts = pm.ls(selection=True) if len(verts) is not 2: message_gui.error("Please select two vertices to interpolate between") return vert1 = verts[0] vert2 = verts[1] if type(vert1) is not pm.general.MeshVertex or type( vert2) is not pm.general.MeshVertex: message_gui.error("Please select two vertices to interpolate between") dialog = ClusterInterpolationWindow(vert1, vert2) dialog.show()
def get_model_alembic_cache(model, project): # 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') if len(geo_files) > 1 or len(geo_files) < 1: if len(geo_files) > 1: details = 'There is more than one alembic file. There should only be one.' else: details = 'There was not an alembic file. It might not have been exported yet.' message_gui.error('There was a problem importing the geo. Please re-export the geo from maya.', details=details) return return geo_files[0]
def exportReferences(destination, tag=None, selectionMode=False, startFrame=1, endFrame=1): if selectionMode: selection = reference_selection.getSelectedReferences() else: selection = reference_selection.getLoadedReferences() if selection is None: return abcFiles = [] for ref in selection: # refNodes = cmds.referenceQuery(unicode(ref), nodes=True) refPath = pm.referenceQuery(unicode(ref), filename=True) print 'the refpath', refPath refNodes = pm.referenceQuery(unicode(refPath), nodes=True) print 'the refNode', refNodes rootNode = pm.ls(refNodes[0])[0] print 'rootNode', rootNode refAbcFilePath = os.path.join(destination, getFilenameForReference(rootNode)) print refAbcFilePath try: if tag is None: command = buildAlembicCommand(refAbcFilePath, startFrame, endFrame, geoList=[rootNode]) else: command = buildTaggedAlembicCommand(rootNode, refAbcFilePath, tag, startFrame, endFrame) print 'Command:', command except NoTaggedGeo, e: message_gui.error('Unable to locate Alembic Export tag for ' + str(ref), title='No Alembic Tag Found') return print 'Export Alembic command: ', command pm.Mel.eval(command) abcFiles.append(refAbcFilePath)
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 createBody(bodyType, name): project = Project() if bodyType == 'asset': msgBox = QtWidgets.QMessageBox() msgBox.setText(msgBox.tr("What type of asset is this?")) # noButton = msgBox.addButton(QtWidgets.QMessageBox.No) # yesButton = msgBox.addButton(QtWidgets.QMessageBox.Yes) cancelButton = msgBox.addButton(QtWidgets.QMessageBox.Cancel) propButton = msgBox.addButton(msgBox.tr("Prop"), QtWidgets.QMessageBox.YesRole) characterButton = msgBox.addButton(msgBox.tr("Character"), QtWidgets.QMessageBox.YesRole) setButton = msgBox.addButton(msgBox.tr("Set"), QtWidgets.QMessageBox.YesRole) msgBox.exec_() if msgBox.clickedButton() == propButton: asset_type = AssetType.PROP elif msgBox.clickedButton() == characterButton: asset_type = AssetType.CHARACTER elif msgBox.clickedButton() == setButton: asset_type = AssetType.SET asset = project.create_asset(name, asset_type) #generate xml for houdini toolshelf try: byu_xml.writeXML(name) except Exception as error: print error message_gui.error(error.args) elif bodyType == 'shot': shot = project.create_shot(name) elif bodyType == 'tool': tool = project.create_tool(name) elif bodyType == 'crowd cycle': cycle = project.create_crowd_cycle(name) else: message_gui.error( bodyType + " is not a valid type!\nThis should not have happend. Please contact a Pipline Management Team member for help!\nTake a screenshot of this error and tell him/her that it came from new_body_gui.py" )
def go(): parent = QtGui.QApplication.activeWindow() if mari.projects.current() is None: message_gui.error( 'You need to have a project open in order to publish it.') return # Get the file location of the mari archive so that the publish windown will get the hightlight right. project_name = mari.projects.current().name() src = project_name index = project_name.find('_texture') if index > 0: environment = Environment() workspace = environment.get_user_workspace() src = os.path.join(workspace, project_name, project_name + '.mra') global mari_publish_dialog mari_publish_dialog = PublishWindow(src, parent, [Department.TEXTURE]) mari_publish_dialog.finished.connect(post_publish)
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 upload_to_sketchfab(data, files, republish=False, uid=None): try: r = None global SKETCHFAB_API_URL if republish: putURL = '{0}/{1}'.format(SKETCHFAB_API_URL, uid) r = requests.put(putURL, **_get_request_payload(data, files=files)) else: r = requests.post(SKETCHFAB_API_URL, data=data, files=files, verify=False) except requests.exceptions.RequestException as e: message_gui.error('An error occured: {}'.format(e)) return result = None try: result = r.json() if r.status_code != requests.codes.created: message_gui.error('Upload failed with error: {}'.format(result)) return except ValueError: print 'There was an error reading the result from the server.' global SKETCHFAB_MODEL_URL model_uid = uid model_url = '' if not result is None: model_uid = result['uid'] if not model_uid is None: model_url = SKETCHFAB_MODEL_URL + model_uid message_gui.input( 'Upload successful. Your model is being processed.\nOnce the processing is done, the model will be available at:', 'Success!', '{}'.format(model_url)) if model_uid == None: return uid else: return model_uid
def rego(): ''' reassembles the currently selected node. That means leaving all of the shop nets in place but throwing out the geo and bringing it in fresh. ''' selection = hou.selectedNodes() if len(selection) > 1: message_gui.error('Please only select one item') return if len(selection) <1: message_gui.error('Please select an item to be reassembled') return hda = selection[0] name = hda.type().name() index = name.rfind('_') main = name[index:] asset_name = name[:index] if main.find('_main') == -1: message_gui.error('There was something wrong with the name. Try tabbing in the asset again and trying one more time.') return project = Project() environment = Environment() username = project.get_current_username() asset = project.get_asset(asset_name) assembly = asset.get_element(Department.ASSEMBLY) # Checkout assembly checkout_file = checkout.checkout_hda(hda, project, environment) reassemble(hda, project, environment, assembly, asset, checkout_file)
def createBody(bodyType, name): project = Project() if bodyType == 'asset': msgBox = QtWidgets.QMessageBox() msgBox.setText(msgBox.tr("What type of asset is this?")) # noButton = msgBox.addButton(QtWidgets.QMessageBox.No) # yesButton = msgBox.addButton(QtWidgets.QMessageBox.Yes) cancelButton = msgBox.addButton(QtWidgets.QMessageBox.Cancel) setButton = msgBox.addButton(msgBox.tr("Set"), QtWidgets.QMessageBox.YesRole) propButton = msgBox.addButton(msgBox.tr("Prop"), QtWidgets.QMessageBox.YesRole) characterButton = msgBox.addButton(msgBox.tr("Character"), QtWidgets.QMessageBox.YesRole) accessoryButton = msgBox.addButton(msgBox.tr("Accessory"), QtWidgets.QMessageBox.YesRole) msgBox.exec_() if msgBox.clickedButton() == propButton: asset_type = AssetType.PROP elif msgBox.clickedButton() == characterButton: asset_type = AssetType.CHARACTER elif msgBox.clickedButton() == setButton: asset_type = AssetType.SET elif msgBox.clickedButton() == accessoryButton: asset_type = AssetType.ACCESSORY print asset_type + " is the asset type" asset = project.create_asset(name, asset_type) elif bodyType == 'shot': shot = project.create_shot(name) elif bodyType == 'tool': tool = project.create_tool(name) else: message_gui.error( bodyType + " is not a valid type!\nThis should not have happend. Please contact a Pipline Management Team member for help!\nTake a screenshot of this error and tell him/her that it came from new_body_gui.py" )