def dcc_set(self, parent, set_name, already_tabbed_in_node=False, mode=UpdateModes.CLEAN): # Check if it's a set and that it exists body = Project().get_body(set_name) if not body.is_asset() or not body.get_type() == AssetType.SET: qd.error("Must be a set.") node = already_tabbed_in_node if already_tabbed_in_node else parent.createNode( "dcc_set") try: node.setName(set_name) except: node.setName(set_name + "_1", unique_name=True) # Update contents in the set self.update_contents_set(node, set_name, mode) return node
def confirmWriteSetReferences(self, body=None): filepath = pm.sceneName() fileDir = 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_asset(): if body.get_type() == AssetType.SET: print("SET OK") element = body.get_element(Department.MODEL) refsfilepath = os.path.join(Project().get_assets_dir(), element.get_cache_dir()) self.exportReferences(refsfilepath) print("JSON references written successfully.") else: print("NOT A SET") qd.error('No set found in current scene.')
def confirmWritePropReference(self, 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] self.exportPropJSON(filePath, non_cameras[0], isReference=False, name=body.get_name()) qd.info("JSON references written successfully.")
def shot_results(self, value): chosen_asset = value[0] project = Project() self.body = project.get_body(chosen_asset) department = Department.LIGHTING element = self.body.get_element(department) #, Element.DEFAULT_NAME) hou.hipFile.save() src = hou.hipFile.name() #Publish user = Environment().get_user() comment = "publish by " + str( user.get_username()) + " in department " + str(department) dst = self.publish_element(element, user, src, comment) message = "Successfully published " + str(self.body.get_name()) + "!" self.print_success_message(message)
def results(self, values): shot_name = str(values[0]) shot = Project().get_body(shot_name) comp_element = shot.get_element(Department.COMP) user_workspace = Environment().get_user_workspace() temp_filepath = os.path.join(user_workspace, shot_name + ".nk") # filepath = nuke.toNode("root").name() #grab name of file they're working on nuke.scriptSave(temp_filepath) print("filepath: ", temp_filepath) user = Environment().get_current_username() comment = qd.input("Comment for publish") if comment is None: comment = "Publish by " + str(user) + " in comp." comp_element.publish(user, temp_filepath, comment) os.environ["DCC_NUKE_ASSET_NAME"] = shot_name qd.info(shot_name + " published successfully.")
def snapshot(self): if self.asset_name: self.shapshot_results([self.asset_name]) return asset_list = Project().list_assets() self.item_gui = sfl.SelectFromList( l=asset_list, parent=maya_main_window(), title="Which asset is this snap for?") self.item_gui.submitted.connect(self.shapshot_results)
def post_publish(element, user, published=True, comment="No comment."): scene_file, created_new_file = get_scene_file() if published: if not mc.file(q=True, sceneName=True) == '': mc.file(save=True, force=True) #save file scene_prep() username = user.get_username() dst = element.publish(username, scene_file, comment) #Ensure file has correct permissions try: os.chmod(dst, 0660) except: print("Setting file permissions failed badly.") # Export JSON print('Publish Complete. Begin Exporting JSON if set.') body = Project().get_body(element.get_parent()) if body and body.is_asset(): if body.get_type() == AssetType.SET or body.get_type( ) == AssetType.SHOT: json_export = JSONExporter() json_export.go(body, body.get_type()) convert_to_education()
def tab_in(self, parent, asset_name, already_tabbed_in_node=None, excluded_departments=[]): print "Creating node for {0}".format(asset_name) body = Project().get_body(asset_name) if body is None or not body.is_asset(): qd.error( "Pipeline error: This asset either doesn't exist or isn't an asset." ) return if body.get_type() == AssetType.CHARACTER: return self.dcc_character(parent, asset_name, already_tabbed_in_node, excluded_departments) elif body.get_type() == AssetType.PROP: return self.dcc_geo(parent, asset_name, already_tabbed_in_node, excluded_departments) elif body.get_type() == AssetType.SET: return self.dcc_set(parent, asset_name, already_tabbed_in_node) else: qd.error( "Pipeline error: this asset isn't a character, prop or set.") return
def publish_hda(self): project = Project() environment = Environment() user = environment.get_user() selectedHDA = self.selectedHDA src = self.src body = self.body asset_type = body.get_type() inside = selectedHDA.node("inside") modify = inside.node("modify") material = inside.node("material") hair = inside.node("hair") cloth = inside.node("cloth") if asset_type == AssetType.CHARACTER: geo = inside.node("geo") geo_inside = geo.node("inside") modify = geo_inside.node("modify") material = geo_inside.node("material") departments_to_publish = [] if not modify is None: departments_to_publish.append("modify") if not material is None: departments_to_publish.append("material") if not hair is None: departments_to_publish.append("hair") if not cloth is None: departments_to_publish.append("cloth") if body is None: qd.error("Asset not found in pipe.") return comment = "publish by " + str(user.get_username( )) + " in departments " + str(departments_to_publish) for department in departments_to_publish: inside = self.get_inside_node(asset_type, department, selectedHDA) node = inside.node(department) src = node.type().definition().libraryFilePath() self.publish_src_node_to_department(src, node, department, user, comment) success_message = "Success! Published to " + str( departments_to_publish) self.print_success_message(success_message) return "published to " + str(departments_to_publish)
def results(self, values): selection = str(values[0]) shot = Project().get_body(selection) comp_element = shot.get_element(Department.COMP) self.publishes = comp_element.list_publishes(); os.environ["DCC_NUKE_ASSET_NAME"] = selection; if not self.publishes: # has not been imported. Import it first. shot_importer = importer.NukeImporter() shot_importer.shot_results([selection]) return else: # get the latest publish username = Environment().get_current_username() filepath = comp_element.checkout(username) if os.path.exists(filepath): nuke.scriptOpen(filepath) else: qd.error("Couldn't find the file.")
def results(self, value): type = value[0] name = self.name # determine if asset was created or not. created = True if name is None or type is None: created = False if created: project = Project() body = project.create_asset(name, asset_type=type) if body == None: # print a message about failure/duplicate qd.error("Asset with name " + str(name) + " already exists in pipeline.") else: prepare_scene_file() # show the gui, get the element. To list elements, get the body and get the department department = "model" # hard-coding model for now since this is Maya asset_list = body.list_elements(department) # get the element for the model dept and the user, and using that publish selected_element = body.get_element("model") user = Environment().get_user() post_publish( selected_element, user, published=True, comment="First commit." ) # FIXME: WE NEED TO FIGURE OUT TO WHICH DEPARTMENT(S) WE ACTUALLY NEED TO PUBLISH TO qd.info("Asset created successfully!", "Success") else: qd.error("Asset creation failed.")
def dcc_geo(self, parent, asset_name, already_tabbed_in_node=None, excluded_departments=[], actor=False, mode=UpdateModes.CLEAN, shot=None): # Set up the body/elements and check if it's an asset. body = Project().get_body(asset_name) if not body.is_asset(): qd.error("Must be an asset.") return None # Set up the nodes, name geo node = already_tabbed_in_node if already_tabbed_in_node else parent.createNode( "dcc_geo") if actor: node.setName("geo") else: try: node.setName(asset_name.title()) except: node.setName(asset_name.title() + "_1", unique_name=True) # Set the asset_name data tag data = node.parm("data").evalAsJSONMap() data["asset_name"] = asset_name node.parm("data").set(data) # Set the contents to the nodes that belong to the asset self.update_contents_geo(node, asset_name, excluded_departments, mode, shot=None) return node
def submit(self): print(self.values) self.button.setText("Loading...") icon_path = os.path.join(Project().get_project_dir(), "pipe", "tools", "_resources", "loading_indicator_transparent.gif") self.movie = QtGui.QMovie(icon_path) self.movie.frameChanged.connect(self.setButtonIcon) if not self.movie.loopCount() == -1: self.movie.finished().connect(self.movie.start()) self.movie.start() self.button.setEnabled(False) self.submitted.emit(self.values) self.close()
def get_body_and_export(self, chosen_asset, export_all=False): project = Project() self.body = project.get_body(chosen_asset) type = self.body.get_type() if type == AssetType.PROP or type == AssetType.ACTOR: creases = qd.yes_or_no("Does this asset use creases?") if creases: self.crease = True if type == AssetType.SHOT: export_all = False self.frame_range = qd.input("How many frames are in this shot?") if self.frame_range is None or self.frame_range == u'': self.frame_range = 1 self.frame_range = str(self.frame_range) if not self.frame_range.isdigit(): qd.error("Invalid frame range input. Setting to 1.") else: self.frame_range = 1 self.body.set_frame_range(self.frame_range) asset_type = self.body.get_type() department_list = get_departments_by_type(asset_type, export=True) if export_all: # tag top level nodes nodes = get_top_level_nodes() print("top level: ", nodes) for node in nodes: tag_node_with_flag(node, "DCC_Alembic_Export_Flag") self.department_results(department_list)
def results(self, value): type = value[0] name = self.name # determine if asset was created or not. created = True if name is None or type is None: created = False if created: project = Project() body = project.create_asset(name, asset_type=type) if body == None: # print a message about failure/duplicate qd.error("Asset with name " + name + " already exists in pipeline.") else: assembler = Assembler() assembler.create_hda(name, body=body) qd.info("Asset created successfully.", "Success") else: qd.error("Asset creation failed.")
def publish(self, quick=True): if quick: shot_name = os.environ.get("DCC_NUKE_ASSET_NAME") else: shot_name = None if shot_name is None: shots = Project().list_shots() self.item_gui = sfl.SelectFromList( l=shots, parent=utils.get_main_window(), title="Select a shot to publish to:") self.item_gui.submitted.connect(self.results) else: self.results([shot_name])
def run(self): self.environment = Environment() self.project = Project() hda_dir = self.environment.get_hda_dir() # GET LIST OF CAMERAS self.cameraList = hou.node('/').recursiveGlob( '*', hou.nodeTypeFilter.ObjCamera) cameraNameList = [camera.name() for camera in self.cameraList] self.item_gui = sfl.SelectFromList( l=cameraNameList, parent=houdini_main_window(), title="Select cameras to snapshot from", multiple_selection=True) self.item_gui.submitted.connect(self.camera_results) print self.item_gui
def asset_results(self, value): chosen_asset = value[0] start_frame = mc.playbackOptions(q=True, min=True) end_frame = mc.playbackOptions(q=True, max=True) submission_location = Project().get_submission_location() playblast_filename = chosen_asset + "_playblast.mov" path = os.path.join(submission_location, playblast_filename) try: self.simple_blast(start_frame, end_frame, path) except Exception as e: qd.error("playblast failed: " + str(e)) return qd.info("Playblast created at " + str(path))
def shotInfo(self, shot_name): print shot_name shot_file = os.path.join(Project().get_shots_dir(), shot_name, "anim", "main", "cache", "animated_props.json") shot_data = None try: with open(shot_file) as f: shot_data = json.load(f) except Exception as error: qd.error("No valid JSON file for " + shot_name) return for asset in shot_data: try: node = hou.node('./inside/' + asset['asset_name']) node.parm('space').set('2') node.parm('shot').set(shot_name) except: print 'error ', asset['asset_name']
def camera_results(self, values): cameras = [] for item in values.items(): if item[1]: cameras.append(item[0]) submission_location = Project().get_submission_location() try: files = self.quick_render(submission_location, cameras) except Exception as e: qd.error("Snapshot failed: " + str(e)) return file_string = "" for dest in files: file_string += str(dest) + "\n" qd.info("Snapshot(s) created at:\n" + file_string)
def post_publish(element, user, export, published=True, comment="No comment."): scene_file, new_file = get_scene_file() username = user.get_username() dst = element.publish(username, scene_file, comment) #Ensure file has correct permissions try: os.chmod(dst, 0660) except: print("Setting file permissions failed.") print('Publish Complete.') body = Project().get_body(element.get_parent()) if export: print("Begin export process.") exporter = Exporter() exporter.auto_export_all() convert_to_education()
def publish_tool(self, node=None): if node is None: node = get_selected_node() if node is None: return node_path = node.path() name = node_path.split('/')[-1] tool_name = name tools = Project().list_hdas() if tool_name not in tools: qd.error("Tool not found in project. Try creating HDA instead.") try: node.type().definition().updateFromNode(node) except hou.OperationFailed, e: qd.error( 'There was a problem publishing the HDA to the pipeline.\n', details=str(e)) return
def publish_content_hda_comment(self, value): node = self.node comment = value if not comment: comment = "published by " + str( user.get_username()) + " in department " + str(department) node_name = node.type().name() index = node_name.rfind('_') asset_name = node_name[:index] department = node_name[index + 1:] self.body = Project().get_body(asset_name) src = node.type().definition().libraryFilePath() user = Environment().get_user() self.publish_src_node_to_department(src, node, department, user, comment) success_message = "Success! Published " + asset_name + " to " + str( department) self.print_success_message(success_message)
def subnet_type(self, asset_name): body = Project().get_body(asset_name) if body is None or not body.is_asset(): qd.error( "Pipeline error: This asset either doesn't exist or isn't an asset." ) return if body.get_type() == AssetType.ACTOR: return "dcc_character" elif body.get_type() == AssetType.PROP: return "dcc_geo" elif body.get_type() == AssetType.SET: return "dcc_set" else: qd.error("Pipeline error: this asset isn't an actor, prop or set.") return
def camera_results(self, value): print(str(value)) cameras = [cam for cam in self.cameraList if cam.name() in value] cur_desktop = hou.ui.curDesktop() desktop = cur_desktop.name() panetab = cur_desktop.paneTabOfType(hou.paneTabType.SceneViewer) persp = panetab.curViewport().name() for cam in cameras: panetab.curViewport().setCamera(cam) default_filename = cam.name() + '_screenshot.jpg' persp = panetab.curViewport().name() filename = hou.ui.selectFile( start_directory=Project().get_submission_location(), title='Select Screenshot File', default_value=default_filename, file_type=hou.fileType.Image) if filename is not None: frame = hou.frame() hou.hscript("viewwrite -f %d %d %s '%s'" % (frame, frame, (desktop + "." + panetab.name() + ".world." + persp), filename))
def has_parent_set(rootNode): project = Project() parent_is_set = False parent_node = rootNode.getParent() while parent_node is not None: print("parent node: ", parent_node) parent_body = get_body_from_reference(parent_node) print("parent body: ", parent_body) if parent_body is not None and parent_body.is_asset() and parent_body.get_type() == AssetType.SET: parent_is_set = True break try: parent_node = parent_node.parent_node() except: print(str(parent_node) + " is top level") parent_node = None if parent_is_set: return True return False
def go(self, node=None): out = hou.node("/out") renderNode = out.createNode("ris", "Render_OUT") shop = hou.node("/shop") risnet = shop.createNode("risnet", "Risnet_OUT") vcm = risnet.createNode("pxrvcm", "PxrVCM_OUT") pathtracer = risnet.createNode("pxrpathtracer", "PxrPathTracer_OUT") renderNode.parm("shop_integratorpath").set("/shop/" + str(risnet) + "/" + str(vcm)) renderNode.parm("camera").set( "/obj/dcc_camera1/_/CameraRig_Camera/CameraRig_CameraShape") renderNode.parm("override_camerares").set(1) renderNode.parm("res_fraction").set("specific") renderNode.parm("res_overridex").set(1920) renderNode.parm("res_overridey").set(1080) renderNode.parm("trange").set("normal") renderNode.parm("ri_quickaov_z_0").set(1) renderNode.parm("ri_device_0").set("openexr") renderNode.parm("allowmotionblur").set(1) assetDirectory = Project().get_assets_dir() hipName = hou.hipFile.name() shot = "" if assetDirectory in hipName: shot = hipName.replace(assetDirectory, '') #shot = shot[1:] shot = shot[0:shot.find("/")] currentDate = datetime.now().strftime("%m_%d_%y-%Hhr_%Mmin_%Ssec") exrName = str(shot) + ".$F4.exr" path = os.path.join(assetDirectory, shot, "render", "main", "cache", currentDate, exrName) print(path) renderNode.parm("ri_display_0").set(path)
def delete_asset_json(self, items_to_delete, set_name): print("deleting asset") set_file_dir = os.path.join(Project().get_assets_dir(), set_name, "model", "main", "cache") delete_dir = "backup" print(set_file_dir) if not os.path.isdir(os.path.join(set_file_dir, delete_dir)): os.makedirs(os.path.join(set_file_dir, delete_dir)) for item in items_to_delete: for ver_num in range(int(item['version_number']) + 1): file_name = str( item['asset_name']) + '_' + str(ver_num) + '.json' old_abs_path = os.path.join(set_file_dir, file_name) new_abs_path = os.path.join(set_file_dir, delete_dir, file_name) print('moving: ' + file_name + ' to ' + os.path.join(delete_dir, file_name)) print(old_abs_path) print(new_abs_path) #need to put this in a try catch block to avoid unnamed asset errors try: os.rename(old_abs_path, new_abs_path) except: print(old_abs_path + ' file doesn\t exist')
def writeXML(assetName='None', context='OBJ'): project = Project() asset_body = project.get_body(assetName) icon = os.path.join('$JOB', 'pipe', 'tools', '_resources', '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 __init__(self, parent, dept_list=Department.ALL): super(CheckoutWindow, self).__init__() self.parent = parent self.project = Project() self.environment = Environment() self.initUI(dept_list)