def execute(self): try: ProductSubscription.delete( self.subscription.ptask_version_spec, self.subscription.product_version_spec, ) except ProductSubscriptionError as e: raise ActionError("Subscription removal failed: " + str(e)) else: if self.interactive: print "\nSubscription removed.\n" if self._no_refresh: return # refresh the subscriptions on disk refresh_action_cls = ActionRegistry().get_action('refresh', 'subs') if not refresh_action_cls: raise ActionError("Could not find sub refresh action.") try: refresh_action = refresh_action_cls( self.subscription.ptask_version.ptask) refresh_action.interactive = False refresh_action() except ActionError as e: raise ActionError("Failed to refresh subs on disk: " + str(e))
def accept(self): # XXX currently assuming exports are fast. exports could be time # consuming. should probably do these in a separate thread or at # least give the user some more feedback about what is happening. self.setEnabled(False) errors = [] publish = self._publish_check.isChecked() version_up = self._version_check.isChecked() for entity in self.entity_widget.selected_entities(): option_widget = self._options[entity]['widget'] desc_edit = self._descriptions[entity]['widget'] try: product_reprs = entity.export( product_desc=desc_edit.text(), version_note=self._note_edit.text(), **option_widget.value) except Exception as e: errors.append(e) else: # XXX should use product update action if publish: for product_repr in product_reprs: product_ver = product_repr.product_version if not product_ver.published: product_ver.publish() if version_up and not errors: version_action_cls = ActionRegistry().get_action('version', 'work') if not version_action_cls: errors.append( "Unable to version up. Could not location version action.") else: version_action = version_action_cls( spec=self.session.ptask_area.spec, description=self._note_edit.text(), ) try: version_action() except Exception as e: errors.append("Unable to version up: " + str(e)) self.setEnabled(True) if errors: error_dialog = QtGui.QErrorMessage(self) error_dialog.setWindowTitle("Export Errors") error_dialog.showMessage( "There were errors during export:<br><br>" + \ "<br>".join([str(e) for e in errors]) ) else: super(EntityExportWizard, self).accept()
def accept(self): if not self._confirm(): return self.session.save() # handles closing the dialog super(PTaskVersionDialog, self).accept() # version up the work area try: version_action_cls = ActionRegistry().get_action('version', 'work') version_action = version_action_cls(self._ptask.spec, **self.options.value) version_action() except ActionError as e: error_dialog = QtGui.QErrorMessage(self.parent()) error_dialog.setWindowTitle('PTask Version Failure') error_dialog.showMessage( "There was an error versioning this ptask:<br><br>" + \ str(e) ) else: QtGui.QMessageBox.question( self, "Version Up Success", "Version up was successful.", buttons=QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Ok, defaultButton=QtGui.QMessageBox.NoButton, )
def _create_product(self, product_desc, version_note, file_type, resolution="none"): # use the product create action to create the product if it doesn't # exist. create_action_cls = ActionRegistry().get_action('create', 'product') if not create_action_cls: raise EntityError("Unable to find product creation action.") create_action = create_action_cls( product=self.display_name, ptask=self.session.ptask_version.ptask_spec, version=self.session.ptask_version.number, category=self.category, description=product_desc, file_type=file_type, resolution=resolution, note=version_note, ) try: create_action() except ActionError as e: raise EntityError("Unable to export entity: " + str(e)) return create_action.product_repr
def execute(self): # ---- get the actions we need create_action_cls = ActionRegistry().get_action('create', 'sub') if not create_action_cls: raise ActionError("Could not find create sub action.") refresh_action_cls = ActionRegistry().get_action('refresh', 'subs') if not refresh_action_cls: raise ActionError("Could not find sub refresh action.") # ---- use the create sub action to create/replace the subs errors = [] for sub in self.subs_to_source: product_version = sub.product_version product = product_version.product try: create_action = create_action_cls( product=product, ptask=self.current_ptask, version=product_version, ptask_version=self.current_ptask_version, no_refresh=True) create_action.interactive = False create_action() except ActionError as e: errors.append(e) # ---- refresh the subs' import dirs try: refresh_action = refresh_action_cls(self.current_ptask) refresh_action.interactive = False refresh_action() except ActionError as e: raise ActionError("Failed to refresh subs on disk: " + str(e)) # ---- spit some errors if need be if errors: raise ActionError("Errors occurred during source:\n" + \ "\n ".join([str(e) for e in errors]))
def _source_another_ptask(self): source_action_class = ActionRegistry().get_action('source', 'ptask') if not source_action_class: raise ActionError("Could not find ptask source action.") try: source_action = source_action_class( source=self.source, destination=self.ptask, force=True, ) source_action.interactive = False source_action() except ActionError as e: raise ActionError("Failed to source ptask: " + str(e)) exceptions = [] # copy the subscriptions from the source ptask self._source_subs(self.source, self.ptask) # recursively create child ptasks from the source for source_child in self.source.children: try: child_spec = \ self.ptask.spec + PTaskSpec.SEPARATOR + source_child.name child_create = PTaskCreateAction( child_spec, ptask_type=source_child.type, description="Sourced from: " + source_child.spec, creator=self.creator, start_date=self.start_date, due_date=self.due_date, source=source_child, force=True, ) child_create.interactive = False child_create() except ActionError as e: exceptions.append(e) if exceptions: msg = "\n".join([str(e) for e in exceptions]) raise ActionError("Problem sourcing: " + self.source.spec + "\n\n" + msg)
def _refresh_subs(self): if self.interactive: print "\nRefreshing subscriptions." # refresh the subscriptions on disk refresh_action_cls = ActionRegistry().get_action('refresh', 'subs') if not refresh_action_cls: raise ActionError("Could not find sub refresh action.") try: refresh_action = refresh_action_cls(self.ptask) refresh_action.interactive = False refresh_action() except ActionError as e: raise ActionError("Failed to refresh subs on disk: " + str(e))
def accept(self): # handles closing the dialog super(FailDialog, self).accept() try: fail_action_cls = ActionRegistry().get_action('fail') fail_action = fail_action_cls(**self.options.value) fail_action() except ActionError as e: error_dialog = QtGui.QErrorMessage(self.parent()) error_dialog.setWindowTitle('DPA Fail Failure') error_dialog.showMessage( "There was an error submitting the fail message:<br><br>" + \ str(e) )
def _source_subs(self, source_ptask, dest_ptask): if self.interactive: print "\nSourcing subscriptions:" dest_ptask_version_spec = dest_ptask.latest_version.spec exceptions = [] for sub in source_ptask.latest_version.subscriptions: try: new_sub = ProductSubscription.create( dest_ptask_version_spec, sub.product_version_spec, ) except ProductSubscriptionError as e: exceptions.append((sub, e)) else: print " " + Style.bright + \ str(sub.product_version_spec) + Style.normal if exceptions: msgs = [] for (sub, e) in exceptions: msgs.append(sub.product_version_spec + ": " + str(e)) raise ActionError( "Unable to copy forward some subscriptions:\n\n" + \ "\n".join(msgs) ) else: # build the import directory... if self.interactive: print "\nRefreshing subscriptions." # refresh the subscriptions on disk refresh_action_cls = ActionRegistry().get_action('refresh', 'subs') if not refresh_action_cls: raise ActionError("Could not find sub refresh action.") try: refresh_action = refresh_action_cls(dest_ptask) refresh_action.interactive = False refresh_action() except ActionError as e: raise ActionError("Failed to refresh subs on disk: " + str(e))
def _sync_latest_remote(self): # sync the local work directory with the contents of the remote work # directory (excluding products and child directories) source_action_class = ActionRegistry().get_action('sync', 'ptask') if not source_action_class: raise ActionError("Could not find ptask source action.") try: source_action = source_action_class( ptask=self.ptask, version="latest", force=True, ) source_action.interactive = False source_action() except ActionError as e: raise ActionError("Failed to sync the remote work directory.")
def _sync_latest(self): ptask = self.session.ptask area = self.session.ptask_area latest_ver = ptask.latest_version area.provision( area.dir(version=latest_ver.number, verify=False)) source_action_class = ActionRegistry().get_action('source', 'ptask') if not source_action_class: raise DarkKnightError("Could not find ptask source action.") source_action = source_action_class( source=ptask, destination=ptask, destination_version=latest_ver, wait=True, ) source_action.interactive = False source_action()
def _source_non_latest(self): source_action_class = ActionRegistry().get_action('source', 'ptask') if not source_action_class: raise ActionError("Could not find ptask source action.") try: source_action = source_action_class( source=self.ptask, source_version=self.source_version, destination=self.ptask, delete=True, ) source_action.interactive = False source_action() except ActionError as e: raise ActionError( "Failed to copy source version into the work directory.".\ format(v=self.latest_version.number) ) else: print "\nSuccessfully copied source version into the work " + \ "directory."
def _sync_latest(self): # make sure the destination directory exists. it should be there # and empty, but just in case... try: self.ptask.area.provision( self.ptask.area.dir( version=self.latest_version.number, verify=False ) ) except PTaskAreaError as e: raise ActionError( "Unable to create missing destination directory." ) # sync the latest version directory with the contents of the work # directory (excluding products and child directories) source_action_class = ActionRegistry().get_action('source', 'ptask') if not source_action_class: raise ActionError("Could not find ptask source action.") try: source_action = source_action_class( source=self.ptask, destination=self.ptask, destination_version=self.latest_version ) source_action.interactive = False source_action() except ActionError as e: raise ActionError( "Failed to copy latest work in to version {v} directory.".\ format(v=self.latest_version.number) )
def _product_render_arnold(self): # get timestamp for all the tasks being submitted now = datetime.datetime.now() render_layers = self._get_render_layers() # figure out the total number of operations to perform for the progress num_ops = 1 + len(render_layers) * len(self._frame_list) # layer > frame num_ops += len(self._frame_list) # frame submission if self._remove_scenes: num_ops += 1 if self._generate_scenes: num_ops += 1 cur_op = 0 progress_dialog = QtGui.QProgressDialog( "Product render...", "", cur_op, num_ops, self) progress_dialog.setWindowTitle("Dark Knight is busy...") progress_dialog.setAutoReset(False) progress_dialog.setLabelText("Preparing maya file for rendering...") progress_dialog.show() ptask = self._cur_ptask ptask_version = self._cur_ptask.version(self._version) ptask_dir = self._cur_ptask.area.dir() ver_dir = ptask.area.dir(version=self._version) # need to get the maya file in the version directory maya_file = self.session.cmds.file(q=True, sceneName=True) maya_file = maya_file.replace(ptask_dir, ver_dir) file_base = os.path.splitext(os.path.split(maya_file)[1])[0] self.session.cmds.setAttr('defaultResolution.width', self._resolution.width) self.session.cmds.setAttr('defaultResolution.height', self._resolution.height) # set the output file naming convention to name.#.ext self.session.cmds.setAttr("defaultRenderGlobals.animation", True) self.session.cmds.setAttr("defaultRenderGlobals.putFrameBeforeExt", True) self.session.cmds.setAttr("defaultRenderGlobals.outFormatControl", False) # set all other cameras to not be renderable (this seems to work) cam_shape_list = self.session.cmds.ls(cameras=True) for cam_shape in cam_shape_list: cam_name = str( self.session.cmds.listRelatives(cam_shape, parent=True)[0]) if cam_name == self._camera: self.session.cmds.setAttr(cam_shape + ".renderable", 1) else: self.session.cmds.setAttr(cam_shape + ".renderable", 0) # ---- sync current work area to version snapshot to render from cur_project = self.session.cmds.workspace(query=True, rootDirectory=True) ver_project = cur_project.replace(ptask_dir, ver_dir) progress_dialog.setLabelText("Sync'ing work to current version...") try: self.session.save() self._sync_latest() except Exception as e: self._show_error("Unable to save & sync the latest work: " + str(e)) self.setEnabled(True) progress_dialog.close() return cur_op += 1 progress_dialog.setValue(cur_op) create_action_cls = ActionRegistry().get_action('create', 'product') if not create_action_cls: progress_dialog.close() raise DarkKnightError("Unable to find product creation action.") # ---- clean up ASSs scene_dir = os.path.join(ver_project, 'arnold', file_base, 'ass') if self._remove_scenes: progress_dialog.setLabelText("Removing ass files...") if os.path.isdir(scene_dir): try: shutil.rmtree(scene_dir) except Exception as e: progress_dialog.close() raise DarkKnightError("Unable to clean up ass files: " + str(e)) cur_op += 1 progress_dialog.setValue(cur_op) # ---- get a list of warnings to ignore #prman_config = ptask.area.config(PRMAN_CONFIG_PATH, # composite_ancestors=True, composite_method="override") #prman_warnings = " ".join( # ["-woff " + w for w in prman_config.get('woff', [])]) # ---- construct scripts for the queue render_summary = [] for render_layer in render_layers: progress_dialog.setLabelText( "Creating product for layer: {rl}...".format(rl=render_layer)) # ensure product exists for each render layer create_action = create_action_cls( product=render_layer, ptask=ptask_version.ptask_spec, version=ptask_version.number, category='imgseq', description=render_layer + " render layer", file_type=self._file_type, resolution=self._res_str, note=self._version_note, ) try: create_action() except ActionError as e: progress_dialog.close() raise DarkKnightError("Unable to create product: " + str(e)) product_repr = create_action.product_repr product_repr_area = product_repr.area progress_dialog.setLabelText( "Provisioning 'queue' directory in product...") # make sure queue directory exists try: product_repr_area.provision('queue') except Exception as e: progress_dialog.close() raise DarkKnightError( "Unable to create queue scripts directory: " + str(e)) queue_dir = product_repr_area.dir(dir_name='queue') tasks_info_file = os.path.join(queue_dir, 'tasks_info.cfg') tasks_info_config = Config() # dpaset command to run dpaset_cmd = 'eval "`dpa env ptask {pt}@{vn}`"'.format( pt=ptask.spec, vn=ptask_version.number) # set group permissions on project dir, recursively os.system("chmod g+rw {pd} -R".format(pd=ver_project)) # figure out the render layer if render_layer == 'masterLayer': layer_index = self.session.cmds.getAttr("defaultRenderLayer.rlid") else: layer_index = self.session.cmds.getAttr(render_layer + ".rlid") frame_scripts = [] for frame in self._frame_list: frame_padded = str(frame).zfill(4) progress_dialog.setLabelText( "Building render shell script for {rl} frame {f}".format( rl=render_layer, f=frame_padded)) script_path = os.path.join(queue_dir, "{rl}.{fn}.sh".format(rl=render_layer, fn=frame_padded)) out_dir = product_repr_area.dir() out_file = os.path.join(out_dir, "{rl}.{fn}.{ft}".\ format(rl=render_layer, fn=frame_padded, ft=self._file_type)) simple_scene = "{proj}arnold/{fb}/ass/{fb}.{fn}.ass".format( proj=ver_project, fb=file_base, fn=frame_padded) layer_scene = "{proj}arnold/{fb}/ass/{fb}_{rl}.{fn}.ass".\ format(proj=ver_project, fb=file_base, fn=frame_padded, rl=render_layer) render_cmd = "/opt/solidangle/arnold-maya2016/bin/kick -dw -v 6 -i $ASS_PATH " render_cmd += "-l /opt/solidangle/arnold-maya2016/shaders " render_cmd += "-l /opt/solidangle/arnold-maya2016/procedurals " render_cmd += "-o {od} ".format(od=out_file) #render_cmd += "-f {rl} ".format(rl=render_layer) #render_cmd += "-p {proj} ".format(proj=ver_project) #render_cmd += "--prman '-t:0 -cwd \"{proj}\" {warn}' ".\dd # format(proj=ver_project, warn=prman_warnings) with open(script_path, "w") as script_file: script_file.write("#!/bin/bash\n\n") # XXX these should happen automatically in the queue... script_file.write("source /DPA/wookie/dpa/bash/startup.bash\n") script_file.write("pipeup\n") # 'kick' command has to be added to $PATH # Create env variable for Arnold License server script_file.write("export [email protected]\n\n") script_file.write("# set the ptask version to render\n") script_file.write(dpaset_cmd + "\n") script_file.write("cd " + ver_project + "\n\n") # Add necessary paths to the environment for XGen script_file.write("export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/autodesk/maya2016/plug-ins/xgen/lib:/usr/autodesk/maya2016/lib:/opt/solidangle/arnold-maya2016/bin\n\n") # the logic for determining which ass will be generated is # unclear at this point. So we'll build a conditional script_file.write("if [[ -f {lr} ]]; then\n".format(lr=layer_scene)) script_file.write(" export ASS_PATH={lr}\n".format(lr=layer_scene)) script_file.write("else\n") script_file.write(" export ASS_PATH={sr}\n".format(sr=simple_scene)) script_file.write("fi\n") script_file.write("# render!\n") script_file.write(render_cmd + "\n\n") script_file.write("chmod 660 {of}\n\n".format( of=os.path.join(out_dir, render_layer + "*." + self._file_type))) os.chmod(script_path, 0770) frame_scripts.append((frame_padded, script_path, out_file)) cur_op += 1 progress_dialog.setValue(cur_op) frame_tasks = [] task_id_base = get_unique_id(product_repr_area.spec, dt=now) tasks_info_config.add('base_id', task_id_base) if self._generate_scenes: frame_queue = 'hold' else: frame_queue = self._render_queue # create frame tasks for (frame, frame_script, out_file) in frame_scripts: progress_dialog.setLabelText( "Submitting frame: " + frame_script) task_id = task_id_base + "_" + frame if not self._debug_mode: # create tasks, don't actually submit yet create_queue_task(frame_queue, frame_script, task_id, output_file=out_file, submit=False, log_path=frame_script + '.log') frame_tasks.append((frame, task_id)) # # resubmit frame-by-frame because # group submit seems to be occasionally # having problems. os.system("cqresubmittask {qn} {tid}".format( qn=frame_queue, tid=task_id)) cur_op += 1 progress_dialog.setValue(cur_op) frame_info = Config() for (frame, task_id) in frame_tasks: frame_info.add(str(frame), task_id) tasks_info_config.add('frame_ids', frame_info) # resubmit all at once (workaround for slow individual submissions) # # This approach seems to be having problems with the server # communications. Switch to frame-by-frame resubmit because # that has worked where this fails #os.system("cqresubmittask {qn} {tid}".format( # qn=frame_queue, tid=task_id_base)) if self._generate_scenes: progress_dialog.setLabelText("Creating ass generation script...") script_path = os.path.join(queue_dir, "{rl}_assgen.sh".format(rl=render_layer)) with open(script_path, "w") as script_file: script_file.write("#!/bin/bash\n\n") # XXX these should happen automatically in the queue... script_file.write("source /DPA/wookie/dpa/bash/startup.bash\n") script_file.write("pipeup\n\n") script_file.write("# set the ptask version to render\n") script_file.write(dpaset_cmd + "\n") script_file.write("cd " + ver_project + "\n\n") script_file.write("# generate the ass files...\n") current_render_layer = render_layer if render_layer == 'masterLayer': current_render_layer = "defaultRenderLayer" switch_render_layer_cmd = "editRenderLayerGlobals " switch_render_layer_cmd += "-currentRenderLayer \"{rl}\"".\ format(rl=current_render_layer) arnold_export_cmd = "arnoldExportAss -f \"{ad}/{fb}_{rl}.ass\" ".\ format(ad=scene_dir, fb=file_base, rl=render_layer) arnold_export_cmd += "-startFrame {sf} -endFrame {ef} -frameStep 1 ".\ format(li=layer_index, sf=self._frange.start, ef=self._frange.end) arnold_export_cmd += "-mask 255 -lightLinks 1 -shadowLinks 1 -cam {cam} ".\ format(cam=self._camera) arnold_export_cmd += "-expandProcedurals " maya_batch_cmd = 'maya2016 -batch -proj "{proj}" '.format( proj=ver_project) maya_batch_cmd += '-command \'{srlc}; {ar}\' '.\ format(srlc=switch_render_layer_cmd, ar=arnold_export_cmd) maya_batch_cmd += '-file "{mf}"'.format(mf=maya_file) script_file.write(maya_batch_cmd + "\n") script_file.write( "\n# make sure project dir has group permissions\n") script_file.write( "chmod g+rw {pd} -R\n\n".format(pd=ver_project)) # submit the frames to render script_file.write("# Submit frames after ass gen \n") for (frame, frame_task) in frame_tasks: script_file.write("cqmovetask {qn} {tid}\n".format( qn=self._render_queue, tid=frame_task)) # changed to move group #script_file.write("cqmovetask {qn} {tid}\n".format( #qn=self._render_queue, tid=task_id_base)) os.chmod(script_path, 0770) # submit the scenegen script progress_dialog.setLabelText( "Submitting ass gen: " + script_path) task_id = task_id_base + "_asses" tasks_info_config.add('assgen_id', task_id) if not self._debug_mode: create_queue_task(self._scenegen_queue, script_path, task_id, output_file=scene_dir, submit=True, log_path=script_path + '.log') cur_op += 1 progress_dialog.setValue(cur_op) cur_op += 1 progress_dialog.setValue(cur_op) progress_dialog.close() render_summary.append( (render_layer, task_id_base, product_repr, queue_dir)) # For now, disable wrangling tickets. bsddb is causing problems # - zshore, 2015-10-23 # if not self._debug_mode: # # ---- dpa specific queue stuff # from cheesyq import DPAWrangler # # create wrangling ticket # wrangle = DPAWrangler.WrangleRecord(task_id_base) # wrangle.frames = self._frame_list # db = DPAWrangler.GetWranglingDB() # db.set(wrangle.baseId, wrangle) # DPAWrangler.AssignWranglerTask("none", task_id_base) wranglecmd = 'cqcreatewrangleitem ' + task_id_base + ' ' for f in self._frame_list: wranglecmd = wranglecmd + str(f) + ' ' print wranglecmd os.system(wranglecmd) tasks_info_config.write(tasks_info_file) os.chmod(tasks_info_file, 0660) if not self._debug_mode: # send msg... msg_title = "Queue submission report: " + \ now.strftime("%Y/%m/%d %H:%M:%S") msg_body = "Submitted the following tasks for " + \ ptask.spec + ":\n\n" msg_body += " Description: " + self._version_note + "\n" msg_body += " Resolution: " + self._res_str + "\n" msg_body += " File type: " + self._file_type + "\n" msg_body += " Camera: " + self._camera + "\n" if self._generate_scenes: msg_body += " Ass gen queue: " + self._scenegen_queue + "\n" msg_body += " Render queue: " + self._render_queue + "\n" msg_body += " Frames: " + str(self._frange) + "\n" msg_body += " Ass directory: " + scene_dir + "\n" msg_body += "\n" for (layer, task_id_base, product_repr, queue_dir) in render_summary: msg_body += " Render layer: " + layer + "\n" msg_body += " Base task ID: " + task_id_base + "\n" msg_body += " Product representation: " + \ product_repr.spec + "\n" msg_body += " Scripts directory: " + queue_dir + "\n" msg_body += "\n" dk_config = ptask.area.config(DK_CONFIG_PATH, composite_ancestors=True, composite_method="append") recipients = dk_config.get('notify', []) recipients.append(current_username()) recipients = emails_from_unames(recipients) notification = Notification(msg_title, msg_body, recipients, sender=User.current().email) notification.send_email()
def accept(self): # XXX currently assuming exports are fast. exports could be time # consuming. should probably do these in a separate thread or at # least give the user some more feedback about what is happening. self.setEnabled(False) try: # hardcoding. bleh. a better solution would be to identify sessions # as a typical file/save operation vs. the mari archive scheme. if self.session.app_name == 'mari': self.session.save(archive=False) else: self.session.save() except Exception as e: error_dialog = QtGui.QErrorMessage(self) error_dialog.setWindowTitle("Save Errors") error_dialog.showMessage( "There was an error saving the session:<br><br>" + str(e)) self.setEnabled(True) return errors = [] publish = self._publish_check.isChecked() version_up = self._version_check.isChecked() for entity in self.entity_widget.selected_entities(): option_widget = self._options[entity]['widget'] desc_edit = self._descriptions[entity]['widget'] try: product_reprs = entity.export( product_desc=desc_edit.text(), version_note=self._note_edit.text(), **option_widget.value) except Exception as e: errors.append(e) else: # XXX should use product update action if publish: for product_repr in product_reprs: product_ver = product_repr.product_version if not product_ver.published: product_ver.publish() if version_up and not errors: # hardcoding again :(. Now that export has finished, go ahead and # archive the mari session if self.session.app_name == 'mari': self.session.save(archive=True) version_action_cls = ActionRegistry().get_action('version', 'work') if not version_action_cls: errors.append( "Unable to version up. Could not location version action.") else: version_action = version_action_cls( spec=self.session.ptask_area.spec, description=self._note_edit.text(), ) try: version_action() except Exception as e: errors.append("Unable to version up: " + str(e)) self.setEnabled(True) if errors: error_dialog = QtGui.QErrorMessage(self) error_dialog.setWindowTitle("Export Errors") error_dialog.showMessage( "There were errors during export:<br><br>" + \ "<br>".join([str(e) for e in errors]) ) else: super(EntityExportWizard, self).accept()
def playblaster(quality, sequence, autoReview): #Does some error checking to ensure the fspattern is correct area = PTaskArea.current() spec = None if area: spec = area.spec else: print "You need to dpaset into a ptask to use this tool." return False currentCam = cmds.modelPanel(cmds.getPanel(wf=True), q=True, cam=True) currentCamMunged = currentCam.replace('|', '_') focalLength = cmds.camera(currentCam, q=True, fl=True) cameraName = currentCamMunged.title() + "Fov" + str(focalLength) print "Camera Name: " + cameraName specName = spec.name(spec).title() if not autoReview: playblastdir = "/scratch" + area.dir() #listing = os.listdir(playblastdir) print "Making directory " + playblastdir os.system("mkdir -p " + playblastdir) #get a listing of the version numbers in the directory nbversions = len(os.listdir(playblastdir)) versionFrame = "%04d" % (nbversions + 1) fileName = "%s/playblast%s%s-%s" % (playblastdir, specName, cameraName, versionFrame) print "writing playblast to file " + fileName + ".mov" xVal = cmds.getAttr('defaultResolution.width') yVal = cmds.getAttr('defaultResolution.height') if sequence: sqMgr = cmds.listConnections('sequenceManager1', s=True, d=False)[0] seqEnd = cmds.getAttr(str(sqMgr) + ".maxFrame") seqStart = cmds.getAttr(str(sqMgr) + ".minFrame") print "SqStart: " + str(seqStart) print "SqEnd: " + str(seqEnd) cmds.playblast(startTime=seqStart, endTime=seqEnd, sequenceTime=sequence, f=fileName, percent=quality, offScreen=True, format="qt", width=xVal, height=yVal) else: cmds.playblast(f=fileName, percent=quality, offScreen=True, format="qt", width=xVal, height=yVal) cmds.deleteUI("PBQuality") os.chmod(fileName + ".mov", 0777) os.system("vlc " + fileName + ".mov &") return True if autoReview: #create a product to put this in xVal = cmds.getAttr('defaultResolution.width') yVal = cmds.getAttr('defaultResolution.height') product_spec = "playblast=movie" product_type = "mov" product_resolution = str(xVal) + "x" + str(yVal) product_description = "auto generated in dpa playblast tool" from dpa.action.registry import ActionRegistry create_action_cls = ActionRegistry().get_action('create', 'product') create_action = create_action_cls(product=product_spec, ptask=spec, description=product_description, file_type=product_type, resolution=product_resolution) try: create_action() except ActionError as e: raise EntityError("Unable to create a product: " + str(e)) #use product to get the directory path area = create_action.product_repr.area playblastdir = area.dir() versionFrame = create_action.product_version.number_padded baseFileName = "playblast%s%s-%s" % (specName, cameraName, versionFrame) fileName = playblastdir + "/" + baseFileName print "writing playblast to file " + fileName + ".mov" if sequence: sqMgr = cmds.listConnections('sequenceManager1', s=True, d=False)[0] seqEnd = cmds.getAttr(str(sqMgr) + ".maxFrame") seqStart = cmds.getAttr(str(sqMgr) + ".minFrame") print "SqStart: " + str(seqStart) print "SqEnd: " + str(seqEnd) cmds.playblast(startTime=seqStart, endTime=seqEnd, sequenceTime=sequence, f=fileName, percent=quality, offScreen=True, format="qt", width=xVal, height=yVal) else: cmds.playblast(f=fileName, percent=quality, offScreen=True, format="qt", width=xVal, height=yVal) cmds.deleteUI("PBQuality") os.chmod(fileName + ".mov", 0777) reviewcmd = "cd " + playblastdir + "; dpacreatereview " + baseFileName + ".mov " + str( create_action.product_repr.spec) print "creating review: " + reviewcmd os.system(reviewcmd) os.system("vlc " + fileName + ".mov &") return True cmds.error("Invalid selections.") return False
def create_product_before_render(node=None): if not node: node = nuke.thisNode() if not node.knob('product_name') or not node.knob('product_desc'): raise Exception("The supplied node is not a WriteProduct node.") print "Creating product for write node... " + str(node) ptask_area = PTaskArea.current() ptask = PTask.get(ptask_area.spec) if ptask_area.version: ptask_version = ptask.version(ptask_area.version) else: ptask_version = ptask.latest_version category = 'imgseq' file_type = node['file_type'].value() if not file_type: file_type = 'exr' product_name = node['product_name'].value() product_desc = node['product_desc'].value() product_ver_note = node['product_ver_note'].value() if not product_desc: raise Exception("Please enter a product description.") width = nuke.value(node.name() + '.width') height = nuke.value(node.name() + '.height') resolution = width + 'x' + height create_action_cls = ActionRegistry().get_action('create', 'product') if not create_action_cls: raise Exception("Unable to find product creation action.") create_action = create_action_cls( product=product_name, ptask=ptask.spec, version=ptask_version.number, category=category, description=product_desc, file_type=file_type, resolution=resolution, note=product_ver_note, ) try: create_action() except ActionError as e: raise Exception("Unable to create product: " + str(e)) out_path = os.path.join(create_action.product_repr.area.path, product_name + '.####.' + file_type) node['file'].setValue(out_path) return create_action.product_repr