def find_input_shape_1(shape): """ Returns the orig input shape (...ShapeOrig') for the specified shape node based on deformer data This function assumes that the specified shape is affected by at least one valid deformer :param shape: str, shape node to find the corresponding input shape for :return: str """ # Get MObject for shape shape_obj = node_utils.get_mobject(shape) # Get inMesh connection attribute in_conn = maya.cmds.listConnections(shape, source=True, destination=False) if not in_conn: return shape # Find connected deformer deformer_history = maya.cmds.ls(maya.cmds.listHistory(shape), type='geometryFilter') if not deformer_history: raise exceptions.ShapeValidDeformerAffectedException(shape) deformer_obj = node_utils.get_mobject(deformer_history[0]) # Get deformer function set deformer_fn = maya.api.OpenMayaAnim.MFnGeometryFilter(deformer_obj) # Get input shape deformer geom_index = deformer_fn.indexForOutputShape(shape_obj) input_shape_obj = deformer_fn.inputShapeAtIndex(geom_index) return maya.api.OpenMaya.MFnDagNode(input_shape_obj).partialPathName()
def get_geo_index(geometry, deformer): """ Returns the geometry index of a shape to a given deformer :param geometry: str, name of shape or parent transform to query :param deformer: str, name of deformery to query """ check_deformer(deformer) geo = geometry if maya.cmds.objectType(geometry) == 'transform': try: geometry = maya.cmds.listRelatives(geometry, s=True, ni=True, pa=True)[0] except Exception: raise exceptions.GeometryException(geo) geo_obj = node.get_mobject(node_name=geometry) deformer_obj = node.get_mobject(node_name=deformer) deformer_fn = maya.api.OpenMayaAnim.MFnGeometryFilter(deformer_obj) try: geo_index = deformer_fn.indexForOutputShape(geo_obj) except Exception: raise exceptions.NotAffectByDeformerException(geometry, deformer) return geo_index
def set_weights(deformer, weights, geometry=None): """ Set the weights for the give ndeformer using the input value list :param deformer: str, deformer to set weights for :param weights: list<float>, input weight value list :param geometry: str, target geometry to apply weights to. If None, use first affected geometry """ # TODO: Make sure dependant functions return objects as OpenMaya1 objects # set_weights function is dependant of MFnWeightGeometryFilter which is not available in OpenMaya 2.0 yet! check_deformer(deformer) if not geometry: geometry = get_affected_geometry(deformer).keys()[0] geo_shape = geometry geo_obj = node.get_mobject(geometry) if geometry and geo_obj.hasFn(maya.api.OpenMaya.MFn.kTransform): geo_shape = maya.cmds.listRelatives(geometry, s=True, ni=True)[0] deformer_fn = get_deformer_fn(deformer) deformer_set_mem = get_deformer_set_members(deformer=deformer, geometry=geo_shape) weights_list = maya.api.OpenMaya.MFloatArray() [weights_list.append(i) for i in weights] deformer_fn.setWeight(deformer_set_mem[0], deformer_set_mem[1], weights_list)
def find_input_shape(shape): """ Returns the input shape ('...ShapeOrig') for the given shape node This function assumes that the specified shape is affected by at least one valid deformer :param shape: The shape node to find the corresponding input shape for :return: str """ if not maya.cmds.objExists(shape): raise exceptions.ShapeException(shape) # Get inMesh connection in_mesh_cnt = maya.cmds.listConnections(shape + '.inMesh', source=True, destination=False, shapes=True) if not in_mesh_cnt: return shape # Check direct mesh (outMesh --> inMesh) connection if str(maya.cmds.objectType(in_mesh_cnt[0])) == 'mesh': return in_mesh_cnt[0] # Find connected deformer deformer_obj = node.get_mobject(in_mesh_cnt[0]) if not deformer_obj.hasFn(maya.api.OpenMaya.MFn.kGeometryFilt): deformer_hist = maya.cmds.listHistory(shape, type='geometryFilter') if not deformer_hist: LOGGER.warning( 'Shape node "{0}" has incoming inMesh connections but is not affected by any valid deformers! ' 'Returning "{0}"!'.format(shape)) return shape else: deformer_obj = node.get_mobject(deformer_obj[0]) deformer_fn = maya.api.OpenMayaAnim.MFnGeometryFilter(deformer_obj) shape_obj = node.get_mobject(shape) geo_index = deformer_fn.indexForOutputShape(shape_obj) input_shape_obj = deformer_fn.inputShapeAtIndex(geo_index) return maya.api.OpenMaya.MFnDependencyNode(input_shape_obj).name()
def get_mesh_vertex_colors(mesh): """ Returns vertex colors applied to given mesh :param mesh:, str mesh shape node we want to check for vertex colors :return: bool """ mesh_node = node.get_mobject(mesh) mesh_vertex_it = api.IterateVertices(mesh_node) return mesh_vertex_it.has_vertex_colors()
def check_all_mesh_vertices_has_vertex_colors(mesh): """ Returns whether or not all vertices of the given mesh have vertex colors applied :param mesh: str, str mesh shape node we want to check for vertex colors :return: bool """ mesh_node = node.get_mobject(mesh) mesh_vertex_it = api.IterateVertices(mesh_node) mesh_vertex_colors = mesh_vertex_it.get_vertex_colors( skip_vertices_without_vertex_colors=False) return None in mesh_vertex_colors.values()
def __init__(self, scene, native_dcc_object): # We make sure that we store native Maya object as an OpenMaya.MObject # Also we store transform and shape information of the wrapped object mobj = node_utils.get_mobject(native_dcc_object) if mobj.apiType() == maya.api.OpenMaya.MFn.kWorld: native_dcc_object = mobj self._maya_shape = None else: native_dcc_object = shape_utils.get_transform(native_dcc_object) self._maya_shape = node_utils.get_shape(native_dcc_object) super(MayaSceneObject, self).__init__(scene, native_dcc_object)
def get_curve_data(curve_shape, space=None): """ Returns curve dat from the given shape node :param curve_shape: str, node that represents nurbs curve shape :param space: :return: dict """ space = space or maya.api.OpenMaya.MSpace.kObject if python.is_string(curve_shape): curve_shape = node_utils.get_mobject(curve_shape) return api_curves.get_curve_data(curve_shape, space)
def process(self, context): assert tpDcc.is_maya( ), 'Validate Proxy Mesh is only available in Maya!' from tpDcc.dccs.maya.core import node, api root_group_name = artellapipe.NamesMgr().solve_name('root_group') proxy_group_name = artellapipe.NamesMgr().solve_name('proxy_group') geo_group_name = artellapipe.NamesMgr().solve_name('geo_group') proxy_geo = artellapipe.NamesMgr().solve_name('proxy_geo') proxy_geo_parent = '{}|{}|{}'.format(root_group_name, proxy_group_name, geo_group_name) assert proxy_geo and tpDcc.Dcc.object_exists( proxy_geo ), 'Proxy geo "{}" does not exist in current scene!'.format(proxy_geo) assert proxy_geo_parent and tpDcc.Dcc.object_exists( proxy_geo_parent ), 'Proxy geo parent "{}" does not exists in current scene!'.format( proxy_geo_parent) proxy_prefix = proxy_geo.split('_')[0] proxy_geos = tpDcc.Dcc.list_nodes('{}_*'.format(proxy_prefix), node_type='transform') or list() assert len( proxy_geos ) == 1, 'Invalid number ({}) of proxy geometries found in current scene: {}'.format( len(proxy_geos), proxy_geos) proxy_geo = proxy_geos[0] proxy_geo_shapes = tpDcc.Dcc.list_shapes(proxy_geo) assert proxy_geo_shapes, 'No sahpes found in proxy geo geometry!' # We check that all vertex colors have vertices_without_vertex_colors = dict() for proxy_shape in proxy_geo_shapes: proxy_shape_node = node.get_mobject(proxy_shape) proxy_shape_vtx_it = api.IterateVertices(proxy_shape_node) proxy_shape_vertex_colors = proxy_shape_vtx_it.get_vertex_colors( skip_vertices_without_vertex_colors=False) for vtx_id, vtx_color in proxy_shape_vertex_colors.items(): if vtx_color: continue if proxy_shape not in vertices_without_vertex_colors: vertices_without_vertex_colors[proxy_shape] = list() vertices_without_vertex_colors[proxy_shape].append(vtx_id) if vertices_without_vertex_colors: context.data[ 'vertices_without_vertex_colors'] = vertices_without_vertex_colors assert not vertices_without_vertex_colors, 'Some vertices of the proxy shapes have no vertex color ' \ 'applied to them: {}!'.format(vertices_without_vertex_colors)
def get_deformer_set_fn(deformer): """ Initializes and return an MFnSet function set attached to the deformer set of the given deformer :param deformer: str, name of the deformer attached to the deformer set to create function set for :return: str """ check_deformer(deformer) deformer_set = get_deformer_set(deformer=deformer) deformer_set_obj = node.get_mobject(node_name=deformer_set) deformer_set_fn = maya.api.OpenMaya.MFnSet(deformer_set_obj) return deformer_set_fn
def get_deformer_set(deformer): """ Returns the deformer set name associated with the given deformer :param deformer: str, name of deformer to return the deform set for :return: str """ check_deformer(deformer) deformer_obj = node.get_mobject(node_name=deformer) deformer_fn = maya.api.OpenMayaAnim.MFnGeometryFilter(deformer_obj) deformer_set_obj = deformer_fn.deformerSet() if deformer_set_obj.isNull(): raise exceptions.DeformerSetExistsException(deformer) return maya.api.OpenMaya.MFnDependencyNode(deformer_set_obj).name()
def _dcc_objects(self, from_selection=False, wildcard='', object_type=None): """ Returns DCC objects from current scene :param from_selection: bool, Whether to return only selected DCC objects or all objects in the scene :param wildcard: str, filter objects by its name :param object_type: int :return: list(variant) """ expression_regex = name_utils.wildcard_to_regex(wildcard) if from_selection: objects = helpers.get_selection_iterator() else: if python.is_string(object_type): objects = maya.cmds.ls(type=object_type, long=True) else: maya_type = dcc.node_types().get( object_type, (maya.api.OpenMaya.MFn.kDagNode, maya.api.OpenMaya.MFn.kCharacter)) objects = list( helpers.get_objects_of_mtype_iterator(maya_type)) if (object_type is not None and object_type != 0) or wildcard: objects_list = list() for obj in objects: if python.is_string(object_type): type_check = True if not object_type else dcc.node_tpdcc_type( obj, as_string=True) == object_type else: type_check = True if not object_type else dcc.node_tpdcc_type( obj) == object_type if wildcard: obj_name = node_utils.get_name(mobj=obj, fullname=False) wildcard_check = expression_regex.match(obj_name) else: wildcard_check = False if type_check and wildcard_check: if python.is_string(obj): obj = node_utils.get_mobject(obj) objects_list.append(obj) objects = objects_list return objects
def set_current_camera(camera_name): """ Sets the camera to be used in the active view :param camera_name: str, name of the camera to use """ view = maya.api.OpenMayaUI.M3dView.active3dView() if maya.cmds.nodeType(camera_name) == 'transform': shapes = maya.cmds.listRelatives(camera_name, shapes=True) if shapes and maya.cmds.nodeType(shapes[0]) == 'camera': camera_name = shapes[0] mobj = node.get_mobject(camera_name) cam = maya.api.OpenMaya.MDagPath(mobj) view.setCamera(cam) maya.cmds.refresh()
def is_shape(obj): """ Check if the specified object is a valid shape node :param obj: str, object to check as a shape node :return: bool """ if not maya.cmds.objExists(obj): return False if not maya.cmds.objectType(obj, isAType='shape'): return False mobj = node_utils.get_mobject(obj) if not mobj.hasFn(maya.api.OpenMaya.MFn.kShape): return False return True
def get_component_count_api(geometry): """ Returns the number of individual components for the given geometry :param geometry: str, geometry to query :return: int """ if not maya.cmds.objExists(geometry): raise exceptions.GeometryExistsException(geometry) geo_obj = node.get_mobject(geometry) if geo_obj.hasFn(maya.OpenMaya.MFn.kTransform): geometry = maya.cmds.listRelatives(geometry, s=True, ni=True, pa=True)[0] geo_path = node.get_mdag_path(geometry) geo_it = maya.OpenMaya.MItGeometry(geo_path) return geo_it.count()
def get_affected_geometry(deformer, return_shapes=False, full_path_names=False): """ Returns a dictionary containing information about geometry affected by a given deformer Dict keys corresponds to affected geometry names and values indicate geometry index to deformer :param deformer: str, name of the deformer to query geometry from :param return_shapes: bool, Whether shape names should be returned instead of transform names :param full_path_names: bool, Whether full path names of affected objects should be returned :return: dict """ check_deformer(deformer=deformer) affected_objects = dict() deformer_obj = node.get_mobject(node_name=deformer) geo_filter_fn = maya.api.OpenMayaAnim.MFnGeometryFilter(deformer_obj) output_object_array = geo_filter_fn.getOutputGeometry() array_length = output_object_array.length() if hasattr( output_object_array, 'length') else len(output_object_array) for i in range(array_length): output_index = geo_filter_fn.indexForOutputShape( output_object_array[i]) output_node = maya.api.OpenMaya.MFnDagNode(output_object_array[i]) if not return_shapes: output_node = maya.api.OpenMaya.MFnDagNode(output_node.parent(0)) if full_path_names: affected_objects[output_node.fullPathName()] = output_index else: affected_objects[output_node.partialPathName()] = output_index return affected_objects
def get_deformer_fn(deformer): """ Initializes and returns an MFnWeightGeometryFilter function set attached to the specific deformer :param deformer: str, name of the deformer to create function set for :return: str """ # TODO: Make sure dependant functions return objects as OpenMaya1 objects # MFnWeightGeometryFilter does not exists in OpenMayaAnim 2.0 yet! Using OpenMaya 1.0 ...') if not maya.cmds.objExists(deformer): raise Exception('Deformer {} does not exists!'.format(deformer)) deformer_obj = node.get_mobject(deformer) try: deformer_fn = maya.api.OpenMayaAnim.MFnWeightGeometryFilter( deformer_obj) except Exception as e: print(str(e)) raise Exception( 'Could not get a geometry filter for deformer "{}"!'.format( deformer)) return deformer_fn