def check_uv_border_crossing(): """checks if any of the uv shells are crossing uv borders """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return all_meshes = pm.ls(type='mesh') mesh_count = len(all_meshes) nodes_with_uvs_crossing_borders = [] from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() if not pm.general.about(batch=1) and mesh_count: pdm.use_ui = True caller = pdm.register(mesh_count, 'check_out_of_space_uvs()') for node in all_meshes: all_uvs = node.getUVs() uv_shell_ids = node.getUvShellsIds() # prepare an empty dict of lists uvs_per_shell = {} for shell_id in range(uv_shell_ids[1]): uvs_per_shell[shell_id] = [[], []] for uv_id in range(len(uv_shell_ids[0])): u = all_uvs[0][uv_id] v = all_uvs[1][uv_id] shell_id = uv_shell_ids[0][uv_id] uvs_per_shell[shell_id][0].append(u) uvs_per_shell[shell_id][1].append(v) # now check all uvs per shell for shell_id in range(uv_shell_ids[1]): us = sorted(uvs_per_shell[shell_id][0]) vs = sorted(uvs_per_shell[shell_id][1]) # check first and last u and v values if int(us[0]) != int(us[-1]) or int(vs[0]) != int(vs[-1]): # they are not equal it is crossing spaces nodes_with_uvs_crossing_borders.append(node) break caller.step() if len(nodes_with_uvs_crossing_borders): # get transform nodes tra_nodes = map(lambda x: x.getParent(), nodes_with_uvs_crossing_borders) pm.select(tra_nodes) raise RuntimeError( """There are nodes with <b>UV-Shells</b> that are crossing <b>UV BORDERS</b>:<br><br>%s""" % '<br>'.join(map(lambda x: x.name(), tra_nodes[:MAX_NODE_DISPLAY])))
def check_uv_existence(): """check if there are uvs in all objects """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return all_meshes = pm.ls(type='mesh') nodes_with_no_uvs = [] for node in all_meshes: if not node.getAttr('intermediateObject'): if not len(node.getUVs(uvSet='map1')[0]): nodes_with_no_uvs.append(node) if len(nodes_with_no_uvs) > 0: # get transform nodes tra_nodes = map( lambda x: x.getParent(), nodes_with_no_uvs ) pm.select(tra_nodes) raise RuntimeError( """There are nodes with <b>no UVs</b>: <br><br>%s""" % '<br>'.join( map(lambda x: x.name(), tra_nodes[:MAX_NODE_DISPLAY]) ) )
def check_model_quality(): """checks the quality of the model """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return pm.select(None) pm.mel.eval( 'polyCleanupArgList 3 { "1","2","0","0","1","0","0","0","0","1e-005",' '"0","0","0","0","0","2","1" };' ) if len(pm.ls(sl=1)) > 0: raise RuntimeError( """There are issues in your model please run:<br><br> <b>PolygonMesh -> Mesh -> Cleanup...</b><br><br> <ul>Check: <li>Faces with more than 4 sides</li> <li>Faces with holes</li> <li>Lamina Faces</li> <li>Non-manifold Geometry</li> </ul>""" )
def check_uvs(): """checks uvs with no uv area The area of a 2d polygon calculation is based on the answer of Darius Bacon in http://stackoverflow.com/questions/451426/how-do-i-calculate-the-surface-area-of-a-2d-polygon """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return def area(p): return 0.5 * abs(sum(x0 * y1 - x1 * y0 for ((x0, y0), (x1, y1)) in segments(p))) def segments(p): return zip(p, p[1:] + [p[0]]) all_meshes = pm.ls(type='mesh') mesh_count = len(all_meshes) from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() if not pm.general.about(batch=1) and mesh_count: pdm.use_ui = True caller = pdm.register(mesh_count, 'check_uvs()') meshes_with_zero_uv_area = [] for node in all_meshes: all_uvs = node.getUVs() try: for i in range(node.numFaces()): uvs = [] for j in range(node.numPolygonVertices(i)): # uvs.append(node.getPolygonUV(i, j)) uv_id = node.getPolygonUVid(i, j) uvs.append((all_uvs[0][uv_id], all_uvs[1][uv_id])) if area(uvs) == 0.0: meshes_with_zero_uv_area.append(node) break except RuntimeError: meshes_with_zero_uv_area.append(node) caller.step() if len(meshes_with_zero_uv_area): pm.select([node.getParent() for node in meshes_with_zero_uv_area]) raise RuntimeError( """There are meshes with no uvs or faces with zero uv area:<br><br> %s""" % '<br>'.join( map(lambda x: x.name(), meshes_with_zero_uv_area[:MAX_NODE_DISPLAY]) ) )
def check_representations(): """checks if the referenced versions are all matching the representation type of the current version """ ref_reprs = [] wrong_reprs = [] v = staging.get('version') if v: r = Representation(version=v) current_repr = r.repr # For **Base** representation # allow any type of representation to be present in the scene if r.is_base(): return for ref in pm.listReferences(): ref_repr = ref.repr if ref_repr is None: # skip this one this is not related to a Stalker Version continue ref_reprs.append([ref, ref_repr]) if ref_repr != current_repr: wrong_reprs.append(ref) else: return if len(wrong_reprs): ref_repr_labels = [] for ref_repr in ref_reprs: ref = ref_repr[0] repr_name = ref_repr[1] color = 'red' if current_repr != repr_name else 'green' ref_repr_labels.append( '<span style="color: %(color)s">%(repr_name)s</span> -> ' '%(ref)s' % { 'color': color, 'repr_name': repr_name, 'ref': ref.refNode.name() } ) raise PublishError( 'You are saving as the <b>%s</b> representation<br>' 'for the current scene, but the following references<br>' 'are not <b>%s</b> representations of their versions:<br><br>' '%s' % ( current_repr, current_repr, '<br>'.join(ref_repr_labels[:MAX_NODE_DISPLAY]) ) )
def check_if_default_shader(): """check if only default shader is assigned """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return if len(pm.ls(mat=1)) > 2: raise PublishError('Use only lambert1 as the shader!')
def check_uvs(): """checks uvs with no uv area The area of a 2d polygon calculation is based on the answer of Darius Bacon in http://stackoverflow.com/questions/451426/how-do-i-calculate-the-surface-area-of-a-2d-polygon """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return def area(p): return 0.5 * abs( sum(x0 * y1 - x1 * y0 for ((x0, y0), (x1, y1)) in segments(p))) def segments(p): return zip(p, p[1:] + [p[0]]) all_meshes = pm.ls(type='mesh') mesh_count = len(all_meshes) from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() if not pm.general.about(batch=1) and mesh_count: pdm.use_ui = True caller = pdm.register(mesh_count, 'check_uvs()') meshes_with_zero_uv_area = [] for node in all_meshes: all_uvs = node.getUVs() try: for i in range(node.numFaces()): uvs = [] for j in range(node.numPolygonVertices(i)): # uvs.append(node.getPolygonUV(i, j)) uv_id = node.getPolygonUVid(i, j) uvs.append((all_uvs[0][uv_id], all_uvs[1][uv_id])) if area(uvs) == 0.0: meshes_with_zero_uv_area.append(node) break except RuntimeError: meshes_with_zero_uv_area.append(node) caller.step() if len(meshes_with_zero_uv_area): pm.select([node.getParent() for node in meshes_with_zero_uv_area]) raise RuntimeError( """There are meshes with no uvs or faces with zero uv area:<br><br> %s""" % '<br>'.join( map(lambda x: x.name(), meshes_with_zero_uv_area[:MAX_NODE_DISPLAY])))
def check_if_default_shader(): """check if only default shader is assigned """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return if len(pm.ls(mat=1)) > 2: raise PublishError( 'Use only lambert1 as the shader!' )
def check_representations(): """checks if the referenced versions are all matching the representation type of the current version """ ref_reprs = [] wrong_reprs = [] v = staging.get('version') if v: r = Representation(version=v) current_repr = r.repr # For **Base** representation # allow any type of representation to be present in the scene if r.is_base(): return for ref in pm.listReferences(): ref_repr = ref.repr if ref_repr is None: # skip this one this is not related to a Stalker Version continue ref_reprs.append([ref, ref_repr]) if ref_repr != current_repr: wrong_reprs.append(ref) else: return if len(wrong_reprs): ref_repr_labels = [] for ref_repr in ref_reprs: ref = ref_repr[0] repr_name = ref_repr[1] color = 'red' if current_repr != repr_name else 'green' ref_repr_labels.append( '<span style="color: %(color)s">%(repr_name)s</span> -> ' '%(ref)s' % { 'color': color, 'repr_name': repr_name, 'ref': ref.refNode.name() }) raise PublishError( 'You are saving as the <b>%s</b> representation<br>' 'for the current scene, but the following references<br>' 'are not <b>%s</b> representations of their versions:<br><br>' '%s' % (current_repr, current_repr, '<br>'.join( ref_repr_labels[:MAX_NODE_DISPLAY])))
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_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_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_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_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_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_out_of_space_uvs(): """checks if there are uvs with u values that are bigger than 10.0 """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return all_meshes = pm.ls(type='mesh') mesh_count = len(all_meshes) nodes_with_out_of_space_uvs = [] from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() if not pm.general.about(batch=1) and mesh_count: pdm.use_ui = True caller = pdm.register(mesh_count, 'check_out_of_space_uvs()') for node in all_meshes: u, v = node.getUVs() u = sorted(u) if u[0] < 0.0 or u[-1] > 10.0 or v[0] < 0.0: nodes_with_out_of_space_uvs.append(node) caller.step() if len(nodes_with_out_of_space_uvs): # get transform nodes tra_nodes = map( lambda x: x.getParent(), nodes_with_out_of_space_uvs ) pm.select(tra_nodes) raise RuntimeError( """There are nodes which have a UV value bigger than <b>10</b>: <br><br>%s""" % '<br>'.join( map(lambda x: x.name(), tra_nodes[: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_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_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_model_quality(): """checks the quality of the model """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return pm.select(None) pm.mel.eval( 'polyCleanupArgList 3 { "1","2","0","0","1","0","0","0","0","1e-005",' '"0","0","0","0","0","2","1" };') if len(pm.ls(sl=1)) > 0: raise RuntimeError( """There are issues in your model please run:<br><br> <b>PolygonMesh -> Mesh -> Cleanup...</b><br><br> <ul>Check: <li>Faces with more than 4 sides</li> <li>Faces with holes</li> <li>Lamina Faces</li> <li>Non-manifold Geometry</li> </ul>""")
def check_uv_existence(): """check if there are uvs in all objects """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return all_meshes = pm.ls(type='mesh') nodes_with_no_uvs = [] for node in all_meshes: if not node.getAttr('intermediateObject'): if not len(node.getUVs(uvSet='map1')[0]): nodes_with_no_uvs.append(node) if len(nodes_with_no_uvs) > 0: # get transform nodes tra_nodes = map(lambda x: x.getParent(), nodes_with_no_uvs) pm.select(tra_nodes) raise RuntimeError( """There are nodes with <b>no UVs</b>: <br><br>%s""" % '<br>'.join(map(lambda x: x.name(), tra_nodes[:MAX_NODE_DISPLAY])))
def check_out_of_space_uvs(): """checks if there are uvs with u values that are bigger than 10.0 """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return all_meshes = pm.ls(type='mesh') mesh_count = len(all_meshes) nodes_with_out_of_space_uvs = [] from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() if not pm.general.about(batch=1) and mesh_count: pdm.use_ui = True caller = pdm.register(mesh_count, 'check_out_of_space_uvs()') for node in all_meshes: u, v = node.getUVs() u = sorted(u) if u[0] < 0.0 or u[-1] > 10.0 or v[0] < 0.0: nodes_with_out_of_space_uvs.append(node) caller.step() if len(nodes_with_out_of_space_uvs): # get transform nodes tra_nodes = map(lambda x: x.getParent(), nodes_with_out_of_space_uvs) pm.select(tra_nodes) raise RuntimeError( """There are nodes which have a UV value bigger than <b>10</b>: <br><br>%s""" % '<br>'.join(map(lambda x: x.name(), tra_nodes[:MAX_NODE_DISPLAY])))
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_uv_border_crossing(): """checks if any of the uv shells are crossing uv borders """ # skip if this is a representation v = staging.get('version') if v and Representation.repr_separator in v.take_name: return all_meshes = pm.ls(type='mesh') mesh_count = len(all_meshes) nodes_with_uvs_crossing_borders = [] from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() if not pm.general.about(batch=1) and mesh_count: pdm.use_ui = True caller = pdm.register(mesh_count, 'check_out_of_space_uvs()') for node in all_meshes: all_uvs = node.getUVs() uv_shell_ids = node.getUvShellsIds() # prepare an empty dict of lists uvs_per_shell = {} for shell_id in range(uv_shell_ids[1]): uvs_per_shell[shell_id] = [[], []] for uv_id in range(len(uv_shell_ids[0])): u = all_uvs[0][uv_id] v = all_uvs[1][uv_id] shell_id = uv_shell_ids[0][uv_id] uvs_per_shell[shell_id][0].append(u) uvs_per_shell[shell_id][1].append(v) # now check all uvs per shell for shell_id in range(uv_shell_ids[1]): us = sorted(uvs_per_shell[shell_id][0]) vs = sorted(uvs_per_shell[shell_id][1]) # check first and last u and v values if int(us[0]) != int(us[-1]) or int(vs[0]) != int(vs[-1]): # they are not equal it is crossing spaces nodes_with_uvs_crossing_borders.append(node) break caller.step() if len(nodes_with_uvs_crossing_borders): # get transform nodes tra_nodes = map( lambda x: x.getParent(), nodes_with_uvs_crossing_borders ) pm.select(tra_nodes) raise RuntimeError( """There are nodes with <b>UV-Shells</b> that are crossing <b>UV BORDERS</b>:<br><br>%s""" % '<br>'.join( map(lambda x: x.name(), tra_nodes[:MAX_NODE_DISPLAY]) ) )
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)))