def shot_results(self, values): selection = str(values[0]) shot = Project().get_body(selection) render_element = shot.get_element(Department.RENDER) render_filepath = str(render_element.get_dir()) + '/' read = nuke.createNode("Read", "file " + str(render_filepath)) comp_element = shot.get_element(Department.COMP) comp_filepath = str(comp_element.get_cache_dir()) comp_filepath = os.path.join(comp_filepath, selection + ".####.jpg") write = nuke.createNode("Write", "file " + comp_filepath)
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() try: filepath = comp_element.checkout(username) except: filepath = comp_element.get_last_publish()[3] if os.path.exists(filepath): qd.info("Opening file, please wait.") nuke.scriptOpen(filepath) else: qd.error("Couldn't find the file.")
def auto_comp(self): nodes = nuke.allNodes() leafNodes = [] mergeNodes = [] reads = False for node in nodes: if node.Class() == 'Read': reads = True name = node.fullName() color_correct_node = nuke.nodes.ColorCorrect(label=name, inputs=[node]) hue_shift_node = nuke.nodes.HueShift( label=name, inputs=[color_correct_node]) hue_shift_node['postage_stamp'].setValue(True) leafNodes.append(hue_shift_node) if reads: merge = nuke.createNode("Merge") for i in range(len(leafNodes)): if i >= 2: merge.setInput(i + 1, leafNodes[i]) else: merge.setInput(i, leafNodes[i]) merge['postage_stamp'].setValue(True) selection = os.environ.get("DCC_NUKE_ASSET_NAME") if not selection or selection == "": comp_filepath = "" else: shot = Project().get_body(selection) comp_element = shot.get_element(Department.COMP) comp_filepath = str(comp_element.get_cache_dir()) comp_filepath = os.path.join(comp_filepath, str(selection) + ".####.jpg") write = nuke.createNode("Write", "file " + str(comp_filepath)) write.setInput(0, merge) viewer = nuke.createNode("Viewer") viewer.setInput(0, merge)
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 import_shot(self, shot_name): shot_name = shot_name[0] # Bring in the body so we can get info body = Project().get_body(shot_name) print("shot name: ", shot_name) print("body: ", str(body)) if not body: qd.error("Error with asset.") return elif not body.is_shot(): qd.error("Body is not shot?") return # Bring in element so we can get cache directory element = body.get_element(Department.ANIM) if not element: qd.error( "Anim department does not exist for {0} ".format(shot_name)) return cache_dir = element.get_cache_dir() sets_json = [] actors_json = [] animated_props_json = [] # open the json files for sets actors and animated props try: with open(os.path.join(cache_dir, "sets.json")) as f: sets_json = json.load(f) except Exception as error: print "{0}/sets.json not found.".format(cache_dir) try: with open(os.path.join(cache_dir, "actors.json")) as f: actors_json = json.load(f) except Exception as error: print "{0}/actors.json not found.".format(cache_dir) try: with open(os.path.join(cache_dir, "animated_props.json")) as f: animated_props_json = json.load(f) except Exception as error: print "{0}/animated_props.json not found.".format(cache_dir) set_nodes = [] actor_nodes = [] animated_prop_nodes = [] print("Loading sets:") for set in sets_json: print("Set: ", set) try: set_node = Assembler().tab_in(hou.node("/obj"), set["asset_name"]) except Exception as e: print "Error with {0}: ".format(set) + str(e) continue set_nodes.append(set_node) print("Loading props in set ", set) for prop in set_node.children(): print("Prop: ", prop) data_parm = prop.parm("data") if data_parm is None: continue data = data_parm.evalAsJSONMap() for animated_prop in animated_props_json: if data["asset_name"] == animated_prop[ "asset_name"] and data[ "version_number"] == animated_prop[ "version_number"]: prop.parm("space").set("anim") prop.parm("shot").set(shot_name) animated_prop_nodes.append(prop) print("Loading actors: ") for actor in actors_json: print("Actor: ", actor) if actor["asset_name"] == "dcc_camera": camera_node = self.tab_in_camera(shot_name) actor_nodes.append(camera_node) continue try: # get the most recent data for this reference asset_name = actor["asset_name"] actor_body = Project().get_body(asset_name) asset_type = actor_body.get_type() try: from pipe.tools.houtools.cloner.cloner import Cloner except: pass actor_node, instances = Cloner().asset_results([asset_name]) # Assembler().update_contents_actor(actor_node, asset_name, shot=shot_name) # actor_node = cloned_subnet.copyTo(inside) # cloned_subnet.destroy() # actor_node = Assembler().dcc_actor(hou.node("/obj"), actor["asset_name"],shot=shot_name) # TODO: add the shot name in the dcc_geo inside dcc_actor if asset_type == AssetType.ACTOR: inside = actor_node.node("inside") geo = inside.node("geo") geo.parm("version_number").setExpression( "ch(\"../../version_number\")", language=hou.exprLanguage.Hscript) geo.parm("space").set("anim") geo.parm("asset_department").set("rig") geo.parm("shot").set(shot_name) elif asset_type == AssetType.PROP: actor_node.parm("version_number").setExpression( "ch(\"../../version_number\")", language=hou.exprLanguage.Hscript) actor_node.parm("space").set("anim") actor_node.parm("asset_department").set("model") actor_node.parm("shot").set(shot_name) actor_nodes.append(actor_node) except Exception as e: print "Error with {0}: ".format(actor) + str(e) continue #shot_parm = actor_node.parm("shot") #shot_parm.set(shot_name) data_parm = actor_node.parm("data") data = data_parm.evalAsJSONMap() data["version_number"] = str(actor["version_number"]) data_parm.set(data) version_number_parm = actor_node.parm("version_number") version_number_parm.set(actor["version_number"]) cam_dir = body.get_element(Department.CAMERA).get_cache_dir() camera_files = os.listdir(cam_dir) cameras = [] for camera_file in camera_files: cameras.append(self.tab_in_camera(str(shot_name), str(camera_file))) # create network box in houdini and fill it with all objects in the shot box = hou.node("/obj").createNetworkBox() box.setComment(shot_name) for set_node in set_nodes: box.addItem(set_node) for actor_node in actor_nodes: box.addItem(actor_node) for animated_prop_node in animated_prop_nodes: box.addItem(animated_prop_node) for camera in cameras: box.addItem(camera) # move all the imported objects to a non-overlaid position in the node editor for set_node in set_nodes: set_node.moveToGoodPosition() for actor_node in actor_nodes: actor_node.moveToGoodPosition() for animated_prop_node in animated_prop_nodes: animated_prop_node.moveToGoodPosition() for camera in cameras: camera.moveToGoodPosition() layout_object_level_nodes()
class Publisher: def __init__(self): self.dcc_geo_departments = [Department.MODIFY, Department.MATERIAL] self.item_gui = None def publish_content_hda(self, node): 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() comment = "publish by " + str( user.get_username()) + " in department " + str(department) 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 publish_asset(self, node=None): self.departments = [ Department.MODIFY, Department.MATERIAL, Department.HAIR, Department.CLOTH ] self.publish(selectedHDA=node) def publish_tool(self, node=None): self.departments = [Department.HDA] self.publish(selectedHDA=node) def publish_set(self, node=None): self.departments = [Department.ASSEMBLY] project = Project() set_list = project.list_sets() self.item_gui = sfl.SelectFromList(l=set_list, parent=houdini_main_window(), title="Select a set to publish") self.item_gui.submitted.connect(self.set_results) def set_results(self, value): set_name = value[0] project = Project() self.body = project.get_body(set_name) obj = hou.node("/obj") set = obj.node(set_name) if set is None: qd.error( "No set found with that name. Please check naming and try again." ) return print("set: ", set) inside = set.node("inside") children = inside.children() set_file = os.path.join(Project().get_assets_dir(), set_name, "model", "main", "cache", "whole_set.json") set_data = [] try: with open(set_file) as f: set_data = json.load(f) except Exception as error: qd.error("No valid JSON file for " + str(set_name)) return items_in_set = [] for item in set_data: item_name = item['asset_name'] item_version = item['version_number'] items_in_set.append(item_name) # TODO: for each child, make sure that it exists in whole_set.json, or add it if it doesn't, or remove it if it does not child_names = [] for child in children: child_path = child.path() name = child_path.split('/')[-1].lower() child_names.append(name) for item in set_data: if str(item['asset_name']) not in child_names: set_data.remove(item) for child in children: print("child: ", child) inside = child.node("inside") out = inside.node("OUT") set_transform = inside.node("set_dressing_transform") child_path = child.path() name = child_path.split('/')[-1].lower() child_body = project.get_body(name) if child_body is None: qd.warning( str(name) + " not found in pipe. Please check that node is named correctly." ) continue # get transform parms: t is translate, r rotate and s scale (with associated x,y,z vals) tx, ty, tz = self.get_transform(set_transform, "tx", "ty", "tz") rx, ry, rz = self.get_transform(set_transform, "rx", "ry", "rz") sx, sy, sz = self.get_transform(set_transform, "sx", "sy", "sz") latest_file, latest_version = self.body.get_latest_json_version( name) if latest_version == int(9): new_version = 0 else: new_version = int(latest_version) + 1 prop_file = os.path.join( Project().get_assets_dir(), set_name, "model", "main", "cache", str(name) + "_" + str(latest_version) + ".json") if name in items_in_set: print("set contains asset: " + str(name)) try: with open(prop_file) as f: prop_data = json.load(f) except Exception as error: qd.warning("No valid JSON file for " + str(name) + ". Skipping changes made to this asset.") continue for set_item in set_data: if str(set_item['asset_name']) == str(name): set_item['version_number'] = new_version break else: print(str(name) + " not found in set file.") path = self.get_prim_path(out) prop_data = { "asset_name": name, "version_number": 0, "path": str(path), "a": [0, 0, 0], "b": [0, 0, 0], "c": [0, 0, 0] } set_data.append({"asset_name": str(name), "version_number": 0}) new_version = 0 new_prop_file = os.path.join( Project().get_assets_dir(), set_name, "model", "main", "cache", str(name) + "_" + str(new_version) + ".json") # get a b and c from prop_data file. Each is an array of size 3, representing x,y,z coords a = prop_data['a'] b = prop_data['b'] c = prop_data['c'] self.update_points_by_geo(out, a, b, c) # put the updated coords back into prop_data prop_data['a'] = a prop_data['b'] = b prop_data['c'] = c # TODO: add a commit and a publish for this set print("prop data (updated): ", prop_data) updated_prop_data = json.dumps(prop_data) outfile = open(new_prop_file, "w") outfile.write(updated_prop_data) outfile.close() print("prop file updated for " + str(name)) self.clear_transform(set_transform) self.update_version_number(child, new_version) import_node = child.node("import") read_from_json = import_node.node("read_from_json") read_from_json.parm("reload").pressButton() outfile = open(set_file, "w") print("set data: ", set_data) updated_set_data = json.dumps(set_data) outfile.write(updated_set_data) outfile.close() qd.info("Set " + str(set_name) + " published successfully!") def update_version_number(self, child, version_number): version_parm = child.parm("version_number").evalAsInt() child.parm("version_number").set(version_number) def get_prim_path(self, out): geo = out.geometry() return geo.findPrimAttrib("path").strings()[0] def update_points_by_geo(self, out, a, b, c): geo = out.geometry() point_a = geo.iterPoints()[0] point_b = geo.iterPoints()[1] point_c = geo.iterPoints()[2] a_x = point_a.position()[0] a_y = point_a.position()[1] a_z = point_a.position()[2] b_x = point_b.position()[0] b_y = point_b.position()[1] b_z = point_b.position()[2] c_x = point_c.position()[0] c_y = point_c.position()[1] c_z = point_c.position()[2] # a is the first point of this object in geo spreadsheet, b is second, c third. a[0] = a_x a[1] = a_y a[2] = a_z b[0] = b_x b[1] = b_y b[2] = b_z c[0] = c_x c[1] = c_y c[2] = c_z def get_transform(self, child, parm1, parm2, parm3): x = child.parm(parm1).evalAsFloat() y = child.parm(parm2).evalAsFloat() z = child.parm(parm3).evalAsFloat() return x, y, z def clear_transform(self, child): parm_scale_list = ["sx", "sy", "sz"] parm_list = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"] for parm in parm_list: if parm not in parm_scale_list: child.parm(parm).set(0.0) else: child.parm(parm).set(1.0) child.parm(parm).eval() def publish_shot(self): scene = hou.hipFile.name() self.departments = [Department.HDA, Department.LIGHTING, Department.FX] project = Project() asset_list = project.list_shots() self.item_gui = sfl.SelectFromList(l=asset_list, parent=houdini_main_window(), title="Select a shot to publish to") self.item_gui.submitted.connect(self.shot_results) 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 publish( self, selectedHDA=None ): #, departments=[Department.HDA, Department.ASSEMBLY, Department.MODIFY, Department.MATERIAL, Department.HAIR, Department.CLOTH]): project = Project() self.selectedHDA = selectedHDA if selectedHDA is None: nodes = hou.selectedNodes() if len(nodes) == 1: selectedHDA = nodes[0] self.selectedHDA = selectedHDA elif len(nodes) > 1: qd.error( 'Too many nodes selected. Please select only one node.') return else: qd.error('No nodes selected. Please select a node.') return if selectedHDA.type().definition() is not None: self.src = selectedHDA.type().definition().libraryFilePath() asset_list = project.list_props_and_characters() self.item_gui = sfl.SelectFromList( l=asset_list, parent=houdini_main_window(), title="Select an asset to publish to") self.item_gui.submitted.connect(self.asset_results) else: qd.error('The selected node is not a digital asset') return def asset_results(self, value): chosen_asset = value[0] project = Project() self.body = project.get_body(chosen_asset) self.publish_hda() 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 get_inside_node(self, type, department, node): # If it's a character and it's not a hair or cloth asset, we need to reach one level deeper. if type == AssetType.CHARACTER and department in self.dcc_geo_departments: inside = node.node("inside/geo/inside") else: inside = node.node("inside") return inside def publish_src_node_to_department(self, src, node, department, user, comment): 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 function on the selected hda. node.type().definition().updateFromNode(node) except hou.OperationFailed, e: qd.error( 'There was a problem publishing the HDA to the pipeline.\n' ) print(str(e)) return try: node.matchCurrentDefinition( ) # this function locks the node for editing. except hou.OperationFailed, e: qd.warning( 'There was a problem while trying to match the current definition. It\'s not a critical problem. Look at it and see if you can resolve the problem. Publish was successful.' ) print(str(e)) element = self.body.get_element(department, Element.DEFAULT_NAME) dst = self.publish_element(element, user, src, comment) print("dst: ", dst) hou.hda.installFile(dst) definition = hou.hdaDefinition(node.type().category(), node.type().name(), dst) definition.setPreferred(True)