def check_empty_shapes(): """checks if there are empty mesh nodes """ empty_shape_nodes = [] for node in pm.ls(type='mesh'): if node.numVertices() == 0: empty_shape_nodes.append(node) if len(empty_shape_nodes) > 0: pm.select(map(lambda x: x.getParent(), empty_shape_nodes)) raise PublishError( 'There are <b>meshes with no geometry</b> in your scene, ' 'please delete them!!!')
def check_only_published_versions_are_used(): """checks if only published versions are used in this scene """ non_published_versions = [] for ref in pm.listReferences(): v = ref.version if v and not v.is_published: non_published_versions.append(v) if len(non_published_versions): raise PublishError( 'Please use only <b>published</b> versions for:<br><br>%s' % '<br>'.join( map(lambda x: x.nice_name, non_published_versions[:MAX_NODE_DISPLAY])))
def check_objects_still_using_default_shader(): """check if there are objects still using the default shader """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return objects_with_default_material = mc.sets('initialShadingGroup', q=1) if objects_with_default_material and len(objects_with_default_material): mc.select(objects_with_default_material) raise PublishError( 'There are objects still using <b>initialShadingGroup</b><br><br>' '%s<br><br>Please assign a proper material to them' % '<br>'.join(objects_with_default_material[:MAX_NODE_DISPLAY]))
def check_old_object_smoothing(): """checking if there are objects with """ meshes_with_smooth_mesh_preview = [] for node in pm.ls(type='mesh'): if node.displaySmoothMesh.get() != 0: meshes_with_smooth_mesh_preview.append(node.getParent()) if len(meshes_with_smooth_mesh_preview) > 0: pm.select(meshes_with_smooth_mesh_preview) raise PublishError( 'Please do not use <b>Smooth Mesh</b> on following nodes:<br><br>' '%s' % '<br>'.join( map(lambda x: x.name(), meshes_with_smooth_mesh_preview[:MAX_NODE_DISPLAY])))
def check_only_supported_materials_are_used(): """check if only supported materials are used """ non_arnold_materials = [] for material in pm.ls(mat=1): if material.name() not in ['lambert1', 'particleCloud1']: if material.type() not in VALID_MATERIALS: non_arnold_materials.append(material) if len(non_arnold_materials): pm.select(non_arnold_materials) raise PublishError( 'There are non-Arnold materials in the scene:<br><br>%s<br><br>' 'Please remove them!!!' % '<br>'.join(map(lambda x: x.name(), non_arnold_materials)))
def check_node_names_with_bad_characters(): """checks node names and ensures that there are no nodes with ord(c) > 127 """ nodes_with_bad_name = [] for node in pm.ls(): if any(map(lambda x: x == '?' or ord(x) > 127, node.name())): nodes_with_bad_name.append(node) if len(nodes_with_bad_name) > 0: pm.select(nodes_with_bad_name) raise PublishError( 'There are nodes with <b>unknown characters</b> in their names:' '<br><br>' '%s' % '<br>'.join( map(lambda x: x.name(), nodes_with_bad_name)[:MAX_NODE_DISPLAY]))
def check_empty_groups(): """check if there are empty groups """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return empty_groups = [] for node in pm.ls(type='transform'): if len(node.listRelatives(children=1)) == 0: empty_groups.append(node) if len(empty_groups): pm.select(empty_groups) raise PublishError('There are <b>empty groups</b> in your scene, ' 'please remove them!!!')
def check_component_edits_on_references(): """check if there are component edits on references """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return import maya.cmds reference_query = maya.cmds.referenceQuery references_with_component_edits = [] from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() all_refs = pm.listReferences(recursive=True) ref_count = len(all_refs) if not pm.general.about(batch=1) and ref_count: pdm.use_ui = True caller = pdm.register( ref_count, 'Checking component edits on %i reference nodes' % ref_count) for ref in all_refs: all_edits = reference_query(ref.refNode.name(), es=True) # joined_edits = '\n'.join(all_edits) # if '.pt[' in joined_edits or '.pnts[' in joined_edits: # references_with_component_edits.append(ref) for edit in all_edits: if '.pt[' in edit or '.pnts[' in edit: references_with_component_edits.append(ref) break caller.step() caller.end_progress() if len(references_with_component_edits): raise PublishError( 'There are <b>component edits</b> on the following References:' '<br><br>%s<br><br>Please remove them!!!' % '<br>'.join( map(lambda x: x.refNode.name(), references_with_component_edits[:MAX_NODE_DISPLAY])))
def check_smartass_animator(): """checks if the smartass animator is trying to create a new version for a completed animation scene silently """ from stalker.models import walk_hierarchy # check the status of this task v = staging.get('version') t = v.task if t.status.code in ['CMPL']: # get the dependent tasks dependent_tasks = t.dependent_of # generate a white list for the resources # so anybody in the white list can publish it white_list_resources = [] dependent_tasks_all_hierarchy = [] for dt in dependent_tasks: for task in walk_hierarchy(dt, 'dependent_of'): white_list_resources.extend(task.resources) white_list_resources.extend(task.responsible) dependent_tasks_all_hierarchy.append(task) white_list_resources = list(set(white_list_resources)) # get the logged in user from stalker import LocalSession local_session = LocalSession() logged_in_user = local_session.logged_in_user # if any of the dependent task has been started so the status is not # WFD or RTS in any of then # # also check if the logged in user is one of the resources of the # dependent tasks if any([t.status.code not in ['WFD', 'RTS'] for t in dependent_tasks_all_hierarchy]) \ and logged_in_user not in white_list_resources: # so the animator is trying to stab behind us # simply f**k him/her # by not allowing to publish the file raise PublishError( "You're not allowed to publish for this task:<br><br>" "Please <b>Request a REVISION</b>!!!!<br>")
def check_if_leaf_mesh_nodes_have_no_transformation(): """checks if all the Mesh transforms have 0 transformation, but it is allowed to move the mesh nodes in space with a parent group node. """ mesh_nodes_with_transform_children = [] for node in pm.ls(dag=1, type='mesh'): parent = node.getParent() tra_under_shape = pm.ls(parent.listRelatives(), type='transform') if len(tra_under_shape): mesh_nodes_with_transform_children.append(parent) if len(mesh_nodes_with_transform_children): pm.select(mesh_nodes_with_transform_children) raise PublishError( 'The following meshes have other objects parented to them:' '\n\n%s' '\n\nPlease remove any object under them!' % '\n'.join( map(lambda x: x.name(), mesh_nodes_with_transform_children[:MAX_NODE_DISPLAY])))
def check_unique_shot_names(): """check if the shot names are unique """ shot_nodes = pm.ls(type='shot') shot_names = [] shots_with_non_unique_shot_names = [] for shot in shot_nodes: shot_name = shot.shotName.get() if shot_name in shot_names: shots_with_non_unique_shot_names.append(shot) else: shot_names.append(shot_name) if len(shots_with_non_unique_shot_names) > 0: raise PublishError( 'The following shots have non-unique shot names:<br>' '<br>' '%s' % (', '.join( map(lambda x: x.shotName.get(), shots_with_non_unique_shot_names))))
def check_if_root_nodes_have_no_transformation(): """checks if transform nodes directly under world have 0 transformations """ root_transform_nodes = auxiliary.get_root_nodes() non_freezed_root_nodes = [] for node in root_transform_nodes: t = node.t.get() r = node.r.get() s = node.s.get() if t.x != 0 or t.y != 0 or t.z != 0 \ or r.x != 0 or r.y != 0 or r.z != 0 \ or s.x != 1 or s.y != 1 or s.z != 1: non_freezed_root_nodes.append(node) if len(non_freezed_root_nodes): pm.select(non_freezed_root_nodes) raise PublishError( 'Please freeze the following node transformations:\n\n%s' % '\n'.join( map(lambda x: x.name(), non_freezed_root_nodes[:MAX_NODE_DISPLAY])))
def check_time_logs(): """do not allow publishing if there is no time logs for the task, do that only for non WFD tasks """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return if v: task = v.task if task.schedule_model == 'effort': now = datetime.datetime.now() task_start = task.computed_start if task.computed_start else task.start task_start = utc_to_local(task_start) if task.status.code != 'WFD' and task_start <= now: if len(task.time_logs) == 0: raise PublishError( '<p>Please create a TimeLog before publishing this ' 'asset:<br><br>' '<a href="%s/tasks/%s/view">Open In WebBrowser</a>' '</p>' % (stalker_server_internal_address, task.id))
def check_all_tx_textures(): """checks if tx textures are created for all of the texture nodes in the current scene """ v = staging.get('version') if v and Representation.repr_separator in v.take_name: return texture_file_paths = [] workspace_path = pm.workspace.path def add_path(path): if path != '': path = os.path.expandvars(path) if not os.path.isabs(path): path = \ os.path.normpath(os.path.join(workspace_path, path)) texture_file_paths.append(path) for node in pm.ls(type='file'): add_path(node.fileTextureName.get()) for node in pm.ls(type='aiImage'): add_path(node.filename.get()) import glob textures_with_no_tx = [] for path in texture_file_paths: tx_path = '%s.tx' % os.path.splitext(path)[0] # replace any <udim> value with * tx_path = tx_path.replace('<udim>', '*') if not len(glob.glob(tx_path)): textures_with_no_tx.append(path) if len(textures_with_no_tx): raise PublishError('There are textures with no <b>TX</b> file!!!')
def check_anim_layers(): """check if there are animation layers on the scene """ if len(pm.ls(type='animLayer')) > 0: raise PublishError( 'There should be no <b>Animation Layers</b> in the scene!!!')
def check_multiple_shot_nodes(): """checks if there are multiple shot nodes """ shot_nodes = pm.ls(type='shot') if len(shot_nodes) > 1: raise PublishError('There is multiple <b>Shot</b> nodes in the scene')
def check_no_references(): """there should be no references """ if len(pm.listReferences()): raise PublishError( 'There should be no <b>References</b> in a <b>Model</b> scene.')
def check_multiple_connections_for_textures(): """check if textures are only used in one material (not liking it very much but it is breaking ASS files. """ # load necessary plugins plugins = ['matrixNodes', 'quatNodes'] for plugin in plugins: if not pm.pluginInfo(plugin, q=1, l=1): pm.loadPlugin(plugin) v = staging.get('version') # skip if skip_types = ['character', 'animation', 'previs'] for t in v.naming_parents: for st in skip_types: if t.type and t.type.name.lower().startswith(st): return # get all the texture nodes from anima.env.mayaEnv import repr_tools reload(repr_tools) # try to find the material it is been used by walking up the connections nodes_with_multiple_materials = [] # by type nodes_to_ignore = pm.ls(type=[ 'hyperLayout', 'shadingEngine', 'materialInfo', 'time', 'unitConversion', 'hyperView' ]) # by name nodes_to_ignore += pm.ls('lambert1') nodes_to_ignore += pm.ls('defaultShaderList*') nodes_to_ignore += pm.ls('defaultTextureList*') nodes_to_ignore += pm.ls('defaultRenderUtilityList*') all_nodes = pm.ls(type=repr_tools.RENDER_RELATED_NODE_TYPES) for node in nodes_to_ignore: if node in all_nodes: all_nodes.remove(node) for node in all_nodes: materials_connected_to_this_node = \ pm.ls(node.listHistory(future=True), mat=True) # remove self from all_nodes if node in materials_connected_to_this_node: materials_connected_to_this_node.remove(node) if len(materials_connected_to_this_node) > 1: nodes_with_multiple_materials.append(node) else: connections_out_of_this_node = node.outputs() [ connections_out_of_this_node.remove(h) for h in nodes_to_ignore if h in connections_out_of_this_node ] if len(set(connections_out_of_this_node)) > 1: nodes_with_multiple_materials.append(node) # if we find more than one material add it to the list # raise a PublishError if we have an item in the list if len(nodes_with_multiple_materials) > 0: pm.select(nodes_with_multiple_materials) raise PublishError( 'Please update the scene so the following nodes are connected <br>' 'to only <b>one material</b> (duplicate them):<br><br>%s<br><br>' % '<br>'.join(map(lambda x: x.name(), nodes_with_multiple_materials)))
def check_sequencer(): """checks if there is a sequencer node in the scene """ sequencers = pm.ls(type='sequencer') if len(sequencers) == 0: raise PublishError('There is no Sequencer node in the scene!!!')
def check_display_layer(): """check if there are display layers """ if len(pm.ls(type='displayLayer')) > 1: raise PublishError( 'There should be no <b>Display Layers</b> in the scene!!!')
def check_extra_cameras(): """checking if there are extra cameras """ if len(pm.ls(type='camera')) > 4: raise PublishError('There should be no extra cameras in your scene!')
def check_shot_nodes(): """checks if there is at least one shot node """ shot_nodes = pm.ls(type='shot') if len(shot_nodes) == 0: raise PublishError('There is no <b>Shot</b> node in the scene')
def check_no_namespace(): """there should be no namespaces in a model file """ if len(pm.listNamespaces()): raise PublishError( 'There should be no <b>Namespaces</b> in a <b>Model</b> scene.')