def _create_collection_attributes(node): """ Create the attributes expected to be on a Collection (set) node. :param node: Collection set node to add attributes to. :type node: str """ attr = const.COLLECTION_ATTR_LONG_NAME_SOLVER_LIST if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, dataType='string') plug = node + '.' + attr maya.cmds.setAttr(plug, lock=True) attr = const.COLLECTION_ATTR_LONG_NAME_SOLVER_RESULTS if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, dataType='string') plug = node + '.' + attr maya.cmds.setAttr(plug, lock=True) attr = const.COLLECTION_ATTR_LONG_NAME_DEVIATION if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, attributeType='double', minValue=-1.0, defaultValue=-1.0, keyable=True) plug = node + '.' + attr maya.cmds.setAttr(plug, lock=True) return
def get_keyframe_times_for_node_attrs(nodes, attrs): """ Query keyframe times on each node attribute (sparse keys) :param nodes: Nodes to query from. :type nodes: [str, ..] :param attrs: Attributes to query keyframes from. :type attrs: [str, ..] :returns: {str: [int, ..]} """ key_times_map = collections.defaultdict(set) for node in nodes: for attr in attrs: plug = node + '.' + attr attr_exists = node_utils.attribute_exists(attr, node) if attr_exists is False: continue settable = maya.cmds.getAttr(plug, settable=True) if settable is False: continue times = maya.cmds.keyframe(plug, query=True, timeChange=True) or [] if len(times) == 0: continue times = [int(t) for t in times] key_times_map[node] |= set(times) key_times_map = {k: list(v) for k, v in key_times_map.items()} return key_times_map
def get_image_plane_shapes_from_camera(cam_tfm, cam_shp): """ Get the list of image plane shape nodes connected to the given camera. :param cam_tfm: Camera transform node. :type cam_tfm: str :param cam_shp: Camera shape node. :type cam_shp: str :returns: The list of image shape nodes, may be an empty list. :rtype: [str, ..] """ assert isinstance(cam_tfm, pycompat.TEXT_TYPE) assert len(cam_tfm) > 0 assert maya.cmds.objExists(cam_tfm) assert isinstance(cam_shp, pycompat.TEXT_TYPE) assert len(cam_shp) > 0 assert maya.cmds.objExists(cam_shp) assert node_utils.attribute_exists('imagePlane', cam_shp) plug = '{0}.imagePlane'.format(cam_shp) img_pl_shps = maya.cmds.listConnections(plug, type='imagePlane') or [] img_pl_shps = [node_utils.get_long_name(n) for n in img_pl_shps] img_pl_shps = [n for n in img_pl_shps if n is not None] return img_pl_shps
def _get_marker_internal_name(mkr): """ Get the Marker object's internal ID (the 'Persistent ID' given from 3DE). :rtype: str or None """ assert isinstance(mkr, mmapi.Marker) node = mkr.get_node() value = None attr_name = 'markerName' if node_utils.attribute_exists(attr_name, node): plug = '{0}.{1}'.format(node, attr_name) value = maya.cmds.getAttr(plug) return value
def _create_marker_attributes(node): """ Create the attributes expected to be on a Marker. :param node: Transform node for the Marker. :type node: str """ attr = const.MARKER_ATTR_LONG_NAME_ENABLE if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, attributeType='short', minValue=0, maxValue=1, defaultValue=1, keyable=True) attr = const.MARKER_ATTR_LONG_NAME_WEIGHT if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, attributeType='double', minValue=0.0, defaultValue=1.0, keyable=True) attr = const.MARKER_ATTR_LONG_NAME_DEVIATION if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, attributeType='double', minValue=-1.0, defaultValue=-1.0, keyable=True) plug = '{0}.{1}'.format(node, attr) maya.cmds.setAttr(plug, lock=True) attr = const.MARKER_ATTR_LONG_NAME_BUNDLE if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, attributeType='message') attr = const.MARKER_ATTR_LONG_NAME_MARKER_NAME if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, dataType='string') plug = '{0}.{1}'.format(node, attr) maya.cmds.setAttr(plug, lock=True) attr = const.MARKER_ATTR_LONG_NAME_MARKER_ID if not node_utils.attribute_exists(attr, node): maya.cmds.addAttr(node, longName=attr, attributeType='long', defaultValue=-1) plug = '{0}.{1}'.format(node, attr) maya.cmds.setAttr(plug, lock=True) return
def add_node_attrs(self, node, attrs, start_frame, end_frame, parents=None): """ Add node attributes into the keyframe times. """ assert isinstance(node, (basestring, str, unicode)) assert isinstance(attrs, (list, tuple)) nodes = [node] if parents is not None: assert isinstance(parents, (list, tuple)) nodes += parents # Times are accumulated for the given 'node' plus all # parent nodes, into the same 'node_uuid'. start = start_frame end = end_frame node_uuid = maya.cmds.ls(node, uuid=True)[0] for node in nodes: for attr in attrs: plug = node + '.' + attr attr_exists = node_utils.attribute_exists(attr, node) if attr_exists is False: continue settable = maya.cmds.getAttr(plug, settable=True) if settable is False: continue times = maya.cmds.keyframe(plug, query=True, timeChange=True) or [] if len(times) == 0: continue if node_uuid not in self._key_times_map: self._key_times_map[node_uuid] = set() times = [int(t) for t in times] self._key_times_map[node_uuid] |= set(times) node_key_times = self._key_times_map.get(node_uuid) key_start = min(node_key_times) key_end = max(node_key_times) start = min(key_start, start) end = max(key_end, end) self._frame_ranges_map[node_uuid] = (start, end) return
def _get_auxiliary_attr(col, attr, key, default_value): """Look up the auxiliary attribute's value, and return a default_value if no attribute exists. :param col: The Collection object to get data for. :type col: Collection :param attr: The Attribute object to get data for. :type attr: Attribute :param key: The unique 'key name' to look-up. This is the name of the unique auxiliary attribute. :type key: str :param default_value: The default value for the attribute, if no auxiliary attribute exists (yet). :type default_value: bool or int or float or str :returns: The value for the auxiliary attribute, or fallback to default_value. :rtype: bool or int or float or str """ value = None attr_node = attr.get_node() aux_name = _get_auxiliary_attr_name(col, attr, key) plug_name = '{0}.{1}'.format(attr_node, aux_name) exists = node_utils.attribute_exists(aux_name, attr_node) if exists is False: if isinstance(default_value, bool): maya.cmds.addAttr(attr_node, longName=aux_name, keyable=False, hidden=True, attributeType='bool') else: maya.cmds.addAttr(attr_node, longName=aux_name, keyable=False, hidden=True) maya.cmds.setAttr(plug_name, default_value) value = default_value else: value = maya.cmds.getAttr(plug_name) return value
def _set_auxiliary_attr(col, attr, key, value): attr_node = attr.get_node() aux_name = _get_auxiliary_attr_name(col, attr, key) plug_name = '{0}.{1}'.format(attr_node, aux_name) exists = node_utils.attribute_exists(aux_name, attr_node) if exists is False: if isinstance(value, bool): maya.cmds.addAttr(attr_node, longName=aux_name, keyable=False, hidden=True, attributeType='bool') else: maya.cmds.addAttr(attr_node, longName=aux_name, keyable=False, hidden=True) maya.cmds.setAttr(plug_name, value) return
def _set_auxiliary_attr(col, attr, key, value): """Look up the auxiliary attribute, and set a value on it. If no auxiliary attribute exists, a new attribute is created and initialized. :param col: The Collection object to set data for. :type col: Collection :param attr: The Attribute object to set data for. :type attr: Attribute :param key: The unique 'key name' to look-up. This is the name of the unique auxiliary attribute. :type key: str :param value: The value for the attribute. :type default_value: bool or int or float or str :rtype: None """ attr_node = attr.get_node() aux_name = _get_auxiliary_attr_name(col, attr, key) plug_name = '{0}.{1}'.format(attr_node, aux_name) exists = node_utils.attribute_exists(aux_name, attr_node) if exists is False: if isinstance(value, bool): maya.cmds.addAttr(attr_node, longName=aux_name, keyable=False, hidden=True, attributeType='bool') else: maya.cmds.addAttr(attr_node, longName=aux_name, keyable=False, hidden=True) maya.cmds.setAttr(plug_name, value) return
def _get_keyframe_times_for_each_node_attr(nodes, attrs, start_frame, end_frame): """ Query keyframe times on each node attribute (sparse keys) """ frame_ranges_map = {} key_times_map = {} total_start = 9999999 total_end = -9999999 for node in nodes: start = start_frame end = end_frame for attr in attrs: plug = node + '.' + attr attr_exists = node_utils.attribute_exists(attr, node) if attr_exists is False: continue settable = maya.cmds.getAttr(plug, settable=True) if settable is False: continue times = maya.cmds.keyframe(plug, query=True, timeChange=True) or [] if len(times) == 0: continue if node not in key_times_map: key_times_map[node] = set() times = [int(t) for t in times] key_times_map[node] |= set(times) node_key_times = key_times_map.get(node) key_start = min(node_key_times) key_end = max(node_key_times) start = min(key_start, start) end = max(key_end, end) frame_ranges_map[node] = (start, end) total_start = min(total_start, start) total_end = max(total_end, end) return total_start, total_end, frame_ranges_map, key_times_map
def _is_rig_node(node): """Check if the node is a rig node.""" if node_utils.attribute_exists(const.SCALE_RIG_IDENTIFIER_ATTR_NAME, node): return True return False
def _convert_node_to_plugs(node, attr, node_type, worldspace_cache=None, type_cache=None): """Logic to decide if this attribute will affect the node.""" plugs = set() node_type_plug = '{0}.{1}'.format(node_type, attr) if node_type == 'camera': # If the attribute affects the camera projection matrix, then # it's important to us. if attr not in CAMERA_ATTRS: return plugs else: # All other nodes, skip if world space is not affected ws = __get_and_fill_cache_value( worldspace_cache, node_type_plug, lambda: maya.cmds.attributeQuery( attr, node=node, affectsWorldspace=True)) if ws is False: return plugs node_attr = '{0}.{1}'.format(node, attr) settable = maya.cmds.getAttr(node_attr, settable=True) if settable is True: typ = __get_and_fill_cache_value( type_cache, node_type_plug, lambda: maya.cmds.getAttr(node_attr, type=True)) if typ in VALID_ATTR_TYPES: plugs.add(node_attr) return plugs # Get plugs connected to this attribute, recursively conn_attrs = maya.cmds.listConnections( node_attr, source=True, destination=False, plugs=True) or [] while len(conn_attrs) > 0: node_attr = conn_attrs.pop() node_attr = _get_full_path_plug(node_attr) settable = maya.cmds.getAttr(node_attr, settable=True) if settable is True: attr = node_attr.rpartition('.')[-1] node_type = maya.cmds.nodeType(node) node_type_plug = '{0}.{1}'.format(node_type, attr) typ = __get_and_fill_cache_value( type_cache, node_type_plug, lambda: maya.cmds.getAttr(node_attr, type=True)) if typ in VALID_ATTR_TYPES: plugs.add(node_attr) continue # Get the plugs that affect this plug. tmp_list = maya.cmds.listConnections( node_attr, source=True, destination=False, plugs=True) or [] # Filter by valid plug types. for tmp in tmp_list: node_ = tmp.partition('.')[0] attr_ = tmp.partition('.')[-1] affects_this_plug = maya.cmds.affects(attr_, node_) or [] for attr__ in affects_this_plug: if not node_utils.attribute_exists(attr__, node_): continue node_attr = node_ + '.' + attr__ compound_attrs = maya.cmds.listAttr(node_attr, multi=True) if len(compound_attrs) > 1: for array_item in compound_attrs: node_attr = node_ + '.' + array_item node_attr = _get_full_path_plug(node_attr) conn_attrs += [node_attr] else: node_attr = _get_full_path_plug(node_attr) conn_attrs += [node_attr] # Only unique attributes. conn_attrs = list(set(conn_attrs)) return plugs