class CameraCreator: def __init__(self): self.project = Project() def go(self): #get shot to add camera to shotList = self.project.list_existing_shots( ) #we shouldn't be adding cameras to shots that haven't been created yet anyway self.item_gui = sfl.SelectFromList( l=shotList, parent=maya_main_window(), title="Select shot to add extra camera to") self.item_gui.submitted.connect(self.shot_results) def shot_results(self, value): shot_name = value[0] shot = self.project.get_shot(shot_name) if shot is None: qd.error("There was a problem loading the shot.") return prevNum = shot.get_camera_number() newNum = prevNum + 1 shot.set_camera_number(newNum) message = "There are now " + str( newNum) + " cameras in shot " + shot_name qd.message(message)
class CameraCloner: def __init__(self): self.project = Project() def clone(self): shot_list = self.project.list_existing_shots() self.item_gui = sfl.SelectFromList(l=shot_list, parent=hou.ui.mainQtWindow(), title="Select a shot to clone from") self.item_gui.submitted.connect(self.shot_results) def shot_results(self, value): self.shot_name = value[0] self.shot = self.project.get_shot(self.shot_name) element = self.shot.get_element(Asset.CAMERA) asset_list = next(os.walk(element._filepath))[1] for name in asset_list: if name == "cache": asset_list.remove(name) asset_list.sort(key=unicode.lower) self.item_gui = sfl.SelectFromList(l=asset_list, parent=hou.ui.mainQtWindow(), title="Select an camera to clone") self.item_gui.submitted.connect(self.camera_results) #this could use some more testing once there's more cameras published def camera_results(self, value): camera_name = value[0] element = self.shot.get_element(os.path.join(Asset.CAMERA, camera_name)) if element.get_last_version < 0: qd.error("There are no publishes for this camera.") return path = element.get_last_publish()[3] cameraNode = hou.node("/obj").createNode("cenoteCamera") cameraNode.setName(self.shot_name + "_camera", 1) cameraNode.parm("fileName").set(path) cameraNode.parm("scale").set(0.01) cameraNode.parm("buildHierarchy").pressButton()
class ShotCloner: def __init__(self): self.project = Project() def clone(self): shot_list = self.project.list_existing_shots() self.item_gui = sfl.SelectFromList(l=shot_list, parent=hou.ui.mainQtWindow(), title="Select a shot to clone") self.item_gui.submitted.connect(self.results) def results(self, value): print("Selected shot: " + value[0]) shot_name = value[0] self.body = Project().get_body(shot_name) self.element = self.body.get_element(Asset.HIP) if self.element.get_last_version() >= 0: #check if checked out if self.element.is_assigned(): assigned_user = self.element.get_assigned_user() username = Environment().get_user().get_username() if not assigned_user == username: qd.error("This shot is currently checked out by " + assigned_user) return else: username = Environment().get_user().get_username() self.element.update_assigned_user(username) path = self.element.get_last_publish()[3] if path: hou.hipFile.load(path) else: qd.error("Nothing was cloned")
class Cloner: def __init__(self): pass def rollback(self): #this was obviously never implemented print("Rollin' Rollin' Rollin' (Back)") def quick_clone(self): ''' Clone the most recent version by default ''' self.quick = True self.go() def clone(self, quick=True): self.quick = quick self.project = Project() type_list = ["Model", "Rig", "Animation", "Camera"] self.item_gui = sfl.SelectFromList( l=type_list, parent=maya_main_window(), title="Select a type of asset to clone") self.item_gui.submitted.connect(self.type_results) def type_results(self, value): self.type = value[0] print(self.type) if self.type == "Model": self.clone_geo() elif self.type == "Rig": self.clone_rig() elif self.type == "Animation": self.clone_anim() elif self.type == "Camera": self.clone_camera() else: qd.error("Stephanie did something wrong, go complain to her :)") return def non_gui_open(self, filePath=None, assetName='Temp'): if filePath == None: print('no file') return if os.path.exists(filePath): mc.file(filePath, open=True, force=True, ignoreVersion=True) print("open file " + assetName) else: print('File does not exist: ' + assetName) def clone_geo(self): self.type = Asset.GEO asset_list = self.project.list_existing_assets() self.item_gui = sfl.SelectFromList(l=asset_list, parent=maya_main_window(), title="Select a model to clone") self.item_gui.submitted.connect(self.results) def clone_rig(self): self.type = Asset.RIG asset_list = self.project.list_existing_assets() self.item_gui = sfl.SelectFromList(l=asset_list, parent=maya_main_window(), title="Select a rig to clone") self.item_gui.submitted.connect(self.results) def clone_anim(self): pm.loadPlugin("AbcImport") self.type = Asset.ANIMATION shot_list = self.project.list_existing_shots() self.item_gui = sfl.SelectFromList(l=shot_list, parent=maya_main_window(), title="Select a shot to clone") self.item_gui.submitted.connect(self.shot_results) def clone_camera(self): pm.loadPlugin("AbcImport") self.type = Asset.CAMERA shot_list = self.project.list_existing_shots() self.item_gui = sfl.SelectFromList(l=shot_list, parent=maya_main_window(), title="Select a shot to clone") self.item_gui.submitted.connect(self.shot_results) def shot_results(self, value): shot_name = value[0] print(shot_name) self.shot = self.project.get_body(shot_name) if self.type == Asset.CAMERA: self.element = self.shot.get_element(Asset.CAMERA) cam_list = next(os.walk(self.element._filepath))[1] for name in cam_list: if not name.startswith(Asset.CAMERA): cam_list.remove(name) cam_list.sort(key=str.lower) print(cam_list) self.item_gui = sfl.SelectFromList( l=cam_list, parent=maya_main_window(), title="Select a camera to clone") self.item_gui.submitted.connect(self.results) elif self.type == Asset.ANIMATION: self.element = self.shot.get_element(Asset.ANIMATION) asset_list = next(os.walk(self.element._filepath))[1] for name in asset_list: if name == "cache": asset_list.remove(name) asset_list.sort(key=str.lower) print(asset_list) self.item_gui = sfl.SelectFromList( l=asset_list, parent=maya_main_window(), title="Select an asset to clone") self.item_gui.submitted.connect(self.results) def asset_results(self, value): asset_name = value[0] print(asset_name) self.type = os.path.join(self.type, asset_name) def get_asset(self, value): asset_name = value[0] print(asset_name) self.type = os.path.join(self.type, asset_name) shot_list = self.project.list_existing_shots() self.item_gui = sfl.SelectFromList(l=shot_list, parent=maya_main_window(), title="Select the shot to clone") self.item_gui.submitted.connect(self.results) def go(self): project = Project() asset_list = project.list_assets() self.item_gui = sfl.SelectFromList(l=asset_list, parent=maya_main_window(), title="Select an asset to clone") self.item_gui.submitted.connect(self.results) def results(self, value): print("Final value: ", value[0]) filename = value[0] self.namespace = filename if self.type == Asset.GEO or self.type == Asset.RIG: body = self.project.get_body(filename) self.body = body element = self.body.get_element(self.type) else: self.body = self.shot element = self.body.get_element(os.path.join(self.type, filename)) if element is None: qd.warning("Nothing was cloned.") return self.element = element if self.quick: latest = element.get_last_publish() if not latest: qd.error("There have been no publishes in this department.") return else: selected_scene_file = latest[3] #if we're cloning a model, lets make sure we're getting the obj instead of the usda if self.type == Asset.GEO: path = selected_scene_file.split(".") selected_scene_file = path[0] + ".obj" self.open_scene_file(selected_scene_file) return self.publishes = element.list_publishes() print("publishes: ", self.publishes) if not self.publishes: qd.error("There have been no publishes in this department.") return # make the list a list of strings, not tuples self.sanitized_publish_list = [] for publish in self.publishes: label = publish[0] + " " + publish[1] + " " + publish[2] self.sanitized_publish_list.append(label) self.item_gui = sfl.SelectFromList(l=self.sanitized_publish_list, parent=maya_main_window(), title="Select publish to clone") self.item_gui.submitted.connect(self.publish_selection_results) def publish_selection_results(self, value): selected_publish = None for item in self.sanitized_publish_list: if value[0] == item: selected_publish = item selected_scene_file = None position = 0 for publish in self.publishes: label = publish[0] + " " + publish[1] + " " + publish[2] if label == selected_publish: version_path = self.element.get_version_dir(position) version_path = os.path.join( version_path, self.name + self.element.get_app_ext()) selected_scene_file = version_path break position += 1 # selected_scene_file is the one that contains the scene file for the selected commit self.open_scene_file(selected_scene_file) def open_scene_file(self, selected_scene_file): if selected_scene_file is not None: if not os.path.exists(selected_scene_file): qd.error( "That publish is missing. It may have been deleted to clear up space." ) return False else: if self.type == Asset.RIG or self.type == Asset.ANIMATION or self.type == Asset.CAMERA: # reference in the file mc.file(selected_scene_file, r=True, ignoreVersion=True, mnc=False, gl=True, ns=":") print("File referenced: " + selected_scene_file) elif self.type == Asset.GEO: # check for import vs reference im = qd.binary_option( "Do you want to import or reference this asset?", "Import", "Reference") if im: # import the geometry mc.file(selected_scene_file, i=True, ignoreVersion=True, mnc=False, gl=True, ns=":") print("File imported: " + selected_scene_file) else: # reference the geometry mc.file(selected_scene_file, r=True, ignoreVersion=True, mnc=False, gl=True, ns=":") print("File referenced: " + selected_scene_file) else: # reference the file mc.file(selected_scene_file, r=True, ignoreVersion=True, mnc=False, gl=True, ns=":") print("File referenced: " + selected_scene_file) return True else: return False
class AnimCloner: def __init__(self): self.project = Project() def clone(self): shot_list = self.project.list_existing_shots() self.item_gui = sfl.SelectFromList(l=shot_list, parent=hou.ui.mainQtWindow(), title="Select a shot to clone from") self.item_gui.submitted.connect(self.shot_results) def shot_results(self, value): self.shot_name = value[0] self.shot = self.project.get_shot(self.shot_name) element = self.shot.get_element(Asset.ANIMATION) asset_list = next(os.walk(element._filepath))[1] for name in asset_list: if name == "cache": asset_list.remove(name) asset_list.sort(key=unicode.lower) self.item_gui = sfl.SelectFromList(l=asset_list, parent=hou.ui.mainQtWindow(), title="Select an asset to clone") self.item_gui.submitted.connect(self.asset_results) def asset_results(self, value): self.asset_name = value[0] element = self.shot.get_element( os.path.join(Asset.ANIMATION, self.asset_name)) if element.get_last_version < 0: qd.error("There are no publishes for this asset in this shot.") return path = element.get_last_publish()[3] self.build_network(path) def build_network(self, path): animNode = hou.node("/obj").createNode("cenoteAnimation") animNode.setName(self.asset_name + "_anim", 1) animNode.parm("fileName").set(path) animNode.parm("scale").set(0.01) animNode.parm("buildHierarchy").pressButton() #animNode.parm("rendersubd").set(True) matPath = self.getMatPath() hdaPath = matPath.split(".")[0] + ".hda" if os.path.exists(hdaPath): hou.hda.installFile(hdaPath) for child in hou.node("/mat").children(): if child.type().name() == re.sub(r'\W+', '', self.asset_name): child.destroy() newMat = hou.node("/mat").createNode( re.sub(r'\W+', '', self.asset_name)) newMat.setName(self.asset_name, 1) newMat.setMaterialFlag(True) animNode.parm("materialPath").set("/mat/" + newMat.name()) else: qd.error( "The material for " + self.asset_name + " needs to be republished before it can be cloned in. Republish the material and try again." ) def getMatPath(self): asset = self.project.get_asset(self.asset_name) element = asset.get_element(Asset.MATERIALS) if element.get_last_version() < 0: return os.path.join(element._filepath, self.asset_name + "_main.usda") path = element.get_last_publish()[3] return path
class BuildShot: def __init__(self): self.project = Project() def build(self): shot_list = self.project.list_existing_shots() self.item_gui = sfl.SelectFromList(l=shot_list, parent=hou.ui.mainQtWindow(), title="Select a shot to clone") self.item_gui.submitted.connect(self.results) def results(self, value): self.shot_name = value[0] self.shotBody = Project().get_body(self.shot_name) camElement = self.shotBody.get_element(Asset.CAMERA) asset_list = next(os.walk(camElement._filepath))[1] for name in asset_list: if name == "cache": asset_list.remove(name) asset_list.sort(key=unicode.lower) if len(asset_list) < 1: qd.error( "There is no camera for this shot, so it cannot be built. Quitting build for shot " + self.shot_name + "...") elif len(asset_list) == 1: self.camResults(asset_list) else: self.item_gui = sfl.SelectFromList( l=asset_list, parent=hou.ui.mainQtWindow(), title="Select a camera to clone") self.item_gui.submitted.connect(self.camera_results) def camResults(self, value): camName = value[0] self.camElement = self.shotBody.get_element( os.path.join(Asset.CAMERA, camName)) options = ["Animation", "Layout", "Lights", "FX"] valueGui = qd.CheckboxSelect( text="Select what to import from this shot", options=options, parent=hou.ui.mainQtWindow(), title="Shot Build Settings") valueGui.submitted.connect(self.options_results) def options_results(self, options): '''for op in options: print(op)''' anim = options[0] layout = options[1] lights = options[2] fx = options[3] isCamera = self.get_camera() if not isCamera: return if anim: isAnim = self.get_all_anim() if not isAnim: qd.message( "There is no animation published for this shot. Continuing to build shot..." ) if layout: isLayout = self.get_layout() if not isLayout: qd.message( "Couldn't clone the layout for this shot. Continuing to build shot..." ) self.sequence_name = self.shot_name[:1] self.sequence = self.project.get_sequence(self.sequence_name) if lights: isLights = self.get_lights() if not isLights: qd.message( "Couldn't clone sequence lighting. Continuing to build shot..." ) if fx: self.get_fx() hou.node("/obj").layoutChildren() self.build_render() def get_camera(self): if self.camElement.get_last_version < 0: qd.error( "There is no camera for this shot, so it cannot be built. Quitting build for shot " + self.shot_name + "...") return False try: path = self.camElement.get_last_publish()[3] cameraNode = hou.node("/obj").createNode("cenoteCamera") cameraNode.setName(self.shot_name + "_camera", 1) cameraNode.parm("fileName").set(path) cameraNode.parm("scale").set(0.01) cameraNode.parm("buildHierarchy").pressButton() return True except Exception as e: print(e) return False def get_all_anim(self): animElement = self.shotBody.get_element(Asset.ANIMATION) asset_list = next(os.walk(animElement._filepath))[1] for name in asset_list: if name == "cache": asset_list.remove(name) asset_list.sort(key=unicode.lower) if len(asset_list) < 1: return False for asset in asset_list: self.get_anim(asset) return True def get_anim(self, asset): element = self.shotBody.get_element( os.path.join(Asset.ANIMATION, asset)) if element.get_last_version() < 0: return False try: path = element.get_last_publish()[3] anim_cloner = AnimCloner() anim_cloner.asset_name = asset anim_cloner.build_network(path) return True except Exception as e: print(e) return False def get_layout(self): layout_element = self.shotBody.get_element(Asset.LAYOUT) path = os.path.join(layout_element._filepath, self.shot_name + ".usda") if not os.path.exists(path): print("Layout path doesn't exist") return False try: layoutUnpacker = LayoutUnpacker() layoutUnpacker.shot_name = self.shot_name layoutUnpacker.unpack(path) return True except Exception as e: print(e) return False def get_lights(self): lightElement = self.sequence.get_element(Asset.LIGHTS) if lightElement.get_last_version() < 0: return False path = lightElement.get_last_publish()[3] hou.hda.installFile(path) try: hda = hou.node("/obj").createNode("sequence_" + self.sequence_name + "_lights") except Exception as e: #qd.error("Couldn't create node of type " + name + ". You should still be able to tab in the node manually.") print(e) return False try: hda.setName(self.sequence_name + "_sequence_lights", 1) except: pass try: hda.allowEditOfContents() except: pass return True def get_fx(self): fxElement = self.sequence.get_element(Asset.HDA) fx_list = next(os.walk(fxElement._filepath))[1] for name in fx_list: if name == "cache": fx_list.remove(name) fx_list.sort(key=unicode.lower) for fx in fx_list: self.get_one_fx(fx) def get_one_fx(self, fx): element = self.sequence.get_element(os.path.join(Asset.HDA, fx)) if element.get_last_version() < 0: return filepath = element.get_last_publish()[3] try: hou.hda.installFile(filepath) except Exception as e: print(e) return try: hda = hou.node("/obj").createNode(fx) except Exception as e: qd.error("Couldn't create node of type " + fx + ". You should still be able to tab in the node manually.") try: hda.setName(fx, 1) except: pass try: hda.allowEditOfContents() except: pass def build_render(self): ris = hou.node("/out").createNode("cenote_layered_render") ris.parm("frame1").set(1) ris.parm("frame2").set(self.shotBody.get_frame_range()) ris.parm("frame3").set(2) selected = None root = hou.node('/') camera_nodes = root.recursiveGlob('*', hou.nodeTypeFilter.ObjCamera) for cam in camera_nodes: if "shot" in cam.name(): selected = cam if not selected: qd.error( "Error selecting camera for render. Will need to be done manually." ) else: ris.parm("camera").set(selected.path()) layers = self.build_layer_string() print(layers) ris.parm("render_layers").set(layers) ris.parm("build_rops").pressButton() for node in ris.children(): if node.type().name() == "tractorsubmit_main": node.parm("job_title").set(self.shot_name + "_Test_Render") else: node.parm("override_camerares").set(True) old = node.parm("ri_display_0").unexpandedString() new = old.replace("render", "testRender") node.parm("ri_display_0").set(new) def build_layer_string(self): first = "" second = "" third = "" total = "" for node in hou.node("/obj").children(): if node.type().name() == "cenoteAnimation": first = first + "[ " + node.name() + " ] " elif node.type().name() == "cenoteLayoutNet": third = third + node.name() + " " elif node.type().name( ) != "cenoteCamera" and not "sequence_lights" in node.name(): second = second + node.name() + " " if len(first) > 0: total = total + first if len(second) > 0: total = total + "[ " + second + "] " if len(third) > 0: total = total + "[ " + third + "]" return total