def test_init(self): # TODO: More exhaustive test. node = maya.cmds.createNode('transform') node = node_utils.get_long_name(node) x = attribute.Attribute(node=node, attr='translateX') y = attribute.Attribute(node=node, attr='ty') self.assertEqual(x.get_node(), node) self.assertEqual(x.get_attr(), 'translateX') self.assertEqual(x.get_name(), '|transform1.translateX') self.assertEqual(y.get_attr(), 'translateY') self.assertEqual(y.get_name(), '|transform1.translateY')
def _get_minimum_number_of_root_frames_for_marker(mkr): min_frames_count = 0 bnd = mkr.get_bundle() if bnd is None: return min_frames_count bnd_node = bnd.get_node() if bnd_node is None: return min_frames_count locked_count = 0 animated_count = 0 static_count = 0 for attr_name in BUNDLE_ATTR_NAMES: attr = attribute.Attribute(node=bnd_node, attr=attr_name) attr_state = attr.get_state() locked_count += int(attr_state == const.ATTR_STATE_LOCKED) static_count += int(attr_state == const.ATTR_STATE_STATIC) animated_count += int(attr_state == const.ATTR_STATE_ANIMATED) if static_count > 0: min_frames_count = 2 elif (animated_count == 3) or (locked_count == 3): min_frames_count = 1 return min_frames_count
def test_is_valid(self): """ Collection validation. Once all pieces are connected, the collection is valid. """ x = collection.Collection() x.create_node('myCollection') self.assertFalse(x.is_valid()) # Solver sol = solver.Solver() x.add_solver(sol) self.assertFalse(x.is_valid()) # Solver (with frame) f = frame.Frame(1) sol.add_frame(f) self.assertFalse(x.is_valid()) # Marker / Bundle cam_tfm = maya.cmds.createNode('transform', name='camera1') cam_shp = maya.cmds.createNode('camera', name='cameraShape1') cam = camera.Camera(shape=cam_shp) bnd = bundle.Bundle().create_node() mkr = marker.Marker().create_node(cam=cam, bnd=bnd) x.add_marker(mkr) self.assertFalse(x.is_valid()) # Attribute node = bnd.get_node() attr = attribute.Attribute(node=node, attr='translateX') x.add_attribute(attr) self.assertTrue(x.is_valid())
def generate_isolate_nodes(kwargs): """ Create a list of Maya nodes to be shown to the user during solving. :param kwargs: Solver keyword arguments. :type kwargs: dict :returns: List of Maya nodes. :rtype: [str, ..] """ nodes = set() attrs = kwargs.get('attr') or [] for attr_name, min_val, max_val, offset_val, scale_val in attrs: attr_obj = attribute.Attribute(name=attr_name) node = attr_obj.get_node() nodes.add(node) markers = kwargs.get('marker') or [] for mkr_node, cam_shp_node, bnd_node in markers: nodes.add(mkr_node) nodes.add(bnd_node) cameras = kwargs.get('camera') or [] for cam_tfm_node, cam_shp_node in cameras: nodes.add(cam_tfm_node) nodes.add(cam_shp_node) return nodes
def __reconnect_animcurves(kwargs, save_node_attrs, force_dg_update=True): f = kwargs.get('frame')[0] maya.cmds.currentTime(f, edit=True, update=False) # Re-connect animCurves, and set the solved values. update_nodes = [] for in_plug_name, out_plug_name in save_node_attrs: if maya.cmds.isConnected(in_plug_name, out_plug_name) is False: v = maya.cmds.getAttr(out_plug_name) maya.cmds.connectAttr(in_plug_name, out_plug_name) attr_obj = attribute.Attribute(name=out_plug_name) tangent_type = 'linear' node = attr_obj.get_node() maya.cmds.setKeyframe( node, attribute=attr_obj.get_attr(), time=f, value=v, inTangentType=tangent_type, outTangentType=tangent_type, ) update_nodes.append(node) else: LOG.error('Nodes are connected. This is WRONG.') raise RuntimeError # force update of Maya. if force_dg_update is True: maya.cmds.dgdirty(update_nodes) return
def test_set_marker_list(self): x = collection.Collection() x.create_node('mySolve') attr_list = [] mkr_list = [] mkr1 = marker.Marker().create_node() mkr_list.append(mkr1) for i in xrange(10): mkr = marker.Marker().create_node() mkr_list.append(mkr) node = maya.cmds.createNode('transform') attr = attribute.Attribute(node=node, attr='translateZ') attr_list.append(attr) x.set_marker_list(mkr_list) x.set_attribute_list(mkr_list) self.assertEqual(x.get_marker_list_length(), 11) mkr_list = [mkr1] x.set_marker_list(mkr_list) self.assertEqual(x.get_marker_list_length(), 1) mkr_list = x.get_marker_list() self.assertEqual(mkr1.get_node(), mkr_list[0].get_node())
def test_get_attribute_list_length(self): x = collection.Collection() x.create_node('mySolve') self.assertEqual(x.get_attribute_list_length(), 0) node = maya.cmds.createNode('transform') attr = attribute.Attribute(node=node, attr='translateX') x.add_attribute(attr) self.assertEqual(x.get_attribute_list_length(), 1)
def get_attribute_list(self): result = [] members = self._set.get_all_members(flatten=False, full_path=True) for member in members: object_type = api_utils.get_object_type(member) if object_type == const.OBJECT_TYPE_ATTRIBUTE: attr = attribute.Attribute(name=member) result.append(attr) return result
def test_get_marker_list(self): x = collection.Collection() x.create_node('mySolve') self.assertEqual(x.get_marker_list_length(), 0) node = maya.cmds.createNode('transform') mkr1 = marker.Marker().create_node() mkr2 = marker.Marker().create_node() attr1 = attribute.Attribute(node=node, attr='translateX') attr2 = attribute.Attribute(node=node, attr='translateY') attr3 = attribute.Attribute(node=node, attr='translateZ') attr4 = attribute.Attribute(node=node, attr='rotateX') attr5 = attribute.Attribute(node=node, attr='rotateY') attr6 = attribute.Attribute(node=node, attr='rotateZ') x.add_marker(mkr1) x.add_marker(mkr2) x.add_attribute(attr1) x.add_attribute(attr2) x.add_attribute(attr3) x.add_attribute(attr4) x.add_attribute(attr5) x.add_attribute(attr6) self.assertEqual(x.get_marker_list_length(), 2)
def test_clear_attribute_list(self): x = collection.Collection() x.create_node('mySolve') attr_list = [] for i in xrange(10): node = maya.cmds.createNode('transform') attr = attribute.Attribute(node=node, attr='translateX') attr_list.append(attr) x.set_attribute_list(attr_list) self.assertEqual(x.get_attribute_list_length(), 10) x.clear_attribute_list() self.assertEqual(x.get_attribute_list_length(), 0)
def test_get_state(self): node = maya.cmds.createNode('transform') node = node_utils.get_long_name(node) # Animated maya.cmds.setKeyframe(node, attribute='rotateY', time=1, value=-1.0) maya.cmds.setKeyframe(node, attribute='rotateY', time=10, value=1.0) # Locked maya.cmds.setAttr(node + '.rotateZ', lock=True) # Connected multdiv = maya.cmds.createNode('multiplyDivide') maya.cmds.connectAttr(multdiv + '.outputX', node + '.translateX') # Create the Attribute objects tx = attribute.Attribute(node=node, attr='translateX') rx = attribute.Attribute(node=node, attr='rotateX') ry = attribute.Attribute(node=node, attr='rotateY') rz = attribute.Attribute(node=node, attr='rotateZ') tx_state = tx.get_state() rx_state = rx.get_state() ry_state = ry.get_state() rz_state = rz.get_state() # test returned states. self.assertEqual(tx_state, const.ATTR_STATE_LOCKED) self.assertEqual(rx_state, const.ATTR_STATE_STATIC) self.assertEqual(ry_state, const.ATTR_STATE_ANIMATED) self.assertEqual(rz_state, const.ATTR_STATE_LOCKED) # test 'is_*' functions. self.assertEqual(tx.is_locked(), True) self.assertEqual(rx.is_static(), True) self.assertEqual(ry.is_animated(), True) self.assertEqual(rz.is_locked(), True)
def __generate_isolate_nodes(kwargs): nodes = set() attrs = kwargs.get('attr') or [] for attr_name, min_val, max_val in attrs: attr_obj = attribute.Attribute(name=attr_name) node = attr_obj.get_node() nodes.add(node) markers = kwargs.get('marker') or [] for mkr_node, cam_shp_node, bnd_node in markers: nodes.add(mkr_node) nodes.add(bnd_node) cameras = kwargs.get('camera') or [] for cam_tfm_node, cam_shp_node in cameras: nodes.add(cam_tfm_node) nodes.add(cam_shp_node) return nodes
def test_add_attribute(self): x = collection.Collection() x.create_node('mySolve') node = maya.cmds.createNode('transform') attr = attribute.Attribute(node=node, attr='translateX') x.add_attribute(attr) attr_list = x.get_attribute_list() self.assertEqual(len(attr_list), 1) self.assertIsInstance(attr_list[0], attribute.Attribute) self.assertIsNot(attr, attr_list[0]) # objects are not the same memory. self.assertEqual(attr.get_node(), attr_list[0].get_node()) # same node self.assertEqual(attr.get_attr(), attr_list[0].get_attr()) # same attr self.assertEqual(attr_list[0].get_name(), attr.get_name()) # same name
def clear_attr_keyframes(kwargs, frames): """ Evaluates the animated attributes at 'frames', then deletes the existing animCurves. :param kwargs: Solver keyword arguments. :type kwargs: dict """ frames = list(sorted(frames)) attrs = kwargs.get('attr') or [] for attr_name, min_val, max_val, offset_val, scale_val in attrs: attr_obj = attribute.Attribute(name=attr_name) if not attr_obj.is_animated(): continue # Get Animation Curve animCurves = maya.cmds.listConnections( attr_name, type='animCurve' ) or [] if len(animCurves) == 0: continue animCurve = animCurves[0] # Query AnimCurve values that we wish to keep. values = [] for f in frames: v = maya.cmds.getAttr( animCurve + '.output', time=float(f), ) values.append(v) # Re-create animCurve. maya.cmds.delete(animCurve) tangent_type = 'linear' for f, v in zip(frames, values): maya.cmds.setKeyframe( attr_name, time=f, value=v, respectKeyable=False, minimizeRotation=False, inTangentType=tangent_type, outTangentType=tangent_type ) return
def disconnect_animcurves(kwargs): """ HACK: Disconnect animCurves from animated attributes, then re-connect afterward. This is to solve a Maya bug, which will not solve values on a single frame. :param kwargs: Solver keyword arguments. :type kwargs: dict :returns: Pairs of source and destination plugs that have been disconnected by this function. :rtype: [(str, str), ..] """ f = kwargs.get('frame')[0] maya.cmds.currentTime(f, edit=True, update=False) save_node_attrs = [] attrs = kwargs.get('attr') or [] for attr_name, min_val, max_val, offset_val, scale_val in attrs: attr_obj = attribute.Attribute(name=attr_name) if attr_obj.is_animated() is False: continue in_plug_name = None out_plug_name = attr_name plug = node_utils.get_as_plug(attr_name) isDest = plug.isDestination() if isDest: connPlugs = OpenMaya.MPlugArray() asDest = True # get the source plugs on the other end of 'plug'. asSrc = False plug.connectedTo(connPlugs, asDest, asSrc) for i, conn in enumerate(connPlugs): connPlug = connPlugs[i] connObj = connPlug.node() if connObj.hasFn(OpenMaya.MFn.kAnimCurve): in_plug_name = connPlug.name() break if in_plug_name is not None: save_node_attrs.append((in_plug_name, out_plug_name)) if maya.cmds.isConnected(in_plug_name, out_plug_name) is True: maya.cmds.disconnectAttr(in_plug_name, out_plug_name) else: LOG.error('Nodes are not connected. This is WRONG.') return save_node_attrs
def reconnect_animcurves(kwargs, save_node_attrs, force_dg_update=True): """ Re-connect animation curves previously disconnected using 'disconnect_animcurves' function :param kwargs: Solver keyword arguments. :type kwargs: dict :param save_node_attrs: List of pairs of Maya node.attrs to be re-connected. :type save_node_attrs: [(str, str), ..] :param force_dg_update: Should the DG network be updated? :type force_dg_update: bool """ f = kwargs.get('frame')[0] maya.cmds.currentTime(f, edit=True, update=False) # Re-connect animCurves, and set the solved values. update_nodes = [] for in_plug_name, out_plug_name in save_node_attrs: if maya.cmds.isConnected(in_plug_name, out_plug_name) is False: v = maya.cmds.getAttr(out_plug_name) maya.cmds.connectAttr(in_plug_name, out_plug_name) attr_obj = attribute.Attribute(name=out_plug_name) tangent_type = 'linear' node = attr_obj.get_node() maya.cmds.setKeyframe( node, attribute=attr_obj.get_attr(), time=f, value=v, inTangentType=tangent_type, outTangentType=tangent_type, ) update_nodes.append(node) else: LOG.error('Nodes are connected. This is WRONG.') raise RuntimeError # force update of Maya. if force_dg_update is True: maya.cmds.dgdirty(update_nodes) return
def test_set_attribute_list(self): x = collection.Collection() x.create_node('mySolve') attr_list = [] for i in xrange(10): node = maya.cmds.createNode('transform') attr = attribute.Attribute(node=node, attr='translateX') attr_list.append(attr) x.set_attribute_list(attr_list) attr_list2 = x.get_attribute_list() self.assertEqual(len(attr_list2), 10) name_list = [] for attr in attr_list2: name = attr.get_name() name_list.append(name) for attr in attr_list: name = attr.get_name() self.assertIn(name, name_list)
def test_add_attribute_list(self): x = collection.Collection() x.create_node('mySolve') attr_list = [] for i in xrange(10): node = maya.cmds.createNode('transform') attr = attribute.Attribute(node=node, attr='rotateX') attr_list.append(attr) x.add_attribute_list(attr_list) attr_list2 = x.get_attribute_list() self.assertEqual(len(attr_list2), 10) self.assertIsInstance(attr_list2[0], attribute.Attribute) node_list = [] for attr in attr_list: node_list.append(attr.get_node()) for attr in attr_list2: node = attr.get_node() self.assertIn(node, node_list)
def __reconnect_animcurves(kwargs, save_node_attrs): f = kwargs.get('frame')[0] maya.cmds.currentTime(f, edit=True, update=False) # Re-connect animCurves, and set the solved values. for in_plug_name, out_plug_name in save_node_attrs: if maya.cmds.isConnected(in_plug_name, out_plug_name) is False: v = maya.cmds.getAttr(out_plug_name) maya.cmds.connectAttr(in_plug_name, out_plug_name) attr_obj = attribute.Attribute(name=out_plug_name) tangent_type = 'linear' maya.cmds.setKeyframe( attr_obj.get_node(), attribute=attr_obj.get_attr(), time=f, value=v, inTangentType=tangent_type, outTangentType=tangent_type, ) else: LOG.error('Nodes are connected. This is WRONG.') return
def test_remove_attribute_list(self): x = collection.Collection() x.create_node('mySolve') attr_list = [] for i in xrange(10): node = maya.cmds.createNode('transform') attr = attribute.Attribute(node=node, attr='rotateY') attr_list.append(attr) x.add_attribute_list(attr_list) self.assertEqual(x.get_attribute_list_length(), 10) # Remove the first half x.remove_attribute_list(attr_list[:5]) self.assertEqual(x.get_attribute_list_length(), 5) # Remove the other half x.remove_attribute_list(attr_list[4:]) self.assertEqual(x.get_attribute_list_length(), 0)
def __disconnect_animcurves(kwargs): # HACK: Disconnect animCurves from animated attributes, # then re-connect afterward. This is to solve a Maya bug, # which will not solve values on a single frame. f = kwargs.get('frame')[0] maya.cmds.currentTime(f, edit=True, update=False) save_node_attrs = [] attrs = kwargs.get('attr') or [] for attr_name, min_val, max_val in attrs: attr_obj = attribute.Attribute(attr_name) if attr_obj.is_animated() is False: continue in_plug_name = None out_plug_name = attr_name plug = api_utils.get_as_plug(attr_name) isDest = plug.isDestination() if isDest: connPlugs = OpenMaya.MPlugArray() asDest = True # get the source plugs on the other end of 'plug'. asSrc = False plug.connectedTo(connPlugs, asDest, asSrc) for i, conn in enumerate(connPlugs): connPlug = connPlugs[i] connObj = connPlug.node() if connObj.hasFn(OpenMaya.MFn.kAnimCurve): # dependsNode = OpenMaya.MFnDependencyNode(connObj) # animCurveName = dependsNode.name() in_plug_name = connPlug.name() break if in_plug_name is not None: save_node_attrs.append((in_plug_name, out_plug_name)) if maya.cmds.isConnected(in_plug_name, out_plug_name) is True: maya.cmds.disconnectAttr(in_plug_name, out_plug_name) else: LOG.error('Nodes are not connected. This is WRONG.') return save_node_attrs