class Component(core.Component): """A Component that generations a skeleton using the cmt.rig.skeleton serializer.""" start_joint = fields.MayaNodeField('start_joint', help_text='The ik spline start joint.') end_joint = fields.MayaNodeField('end_joint', help_text='The ik spline end joint.') start_control = fields.MayaNodeField( 'start_control', help_text='The control at the base of the spine.') end_control = fields.MayaNodeField( 'end_control', help_text='The control at the top of the spine.') system_name = fields.CharField( 'system_name', default='spine', help_text='The name of the system used with all the created nodes.') @classmethod def image_path(cls): return shortcuts.get_icon_path('spine') def execute(self): start_joint = self.start_joint.value() end_joint = self.end_joint.value() start_control = self.start_control.value() end_control = self.end_control.value() name = self.system_name.value() splineik.create_spine(start_joint, end_joint, start_control, end_control, name)
def __init__(self, start_joint='', end_joint='', start_control='', end_control='', name='spine', **kwargs): super(Component, self).__init__(**kwargs) self.start_joint = fields.MayaNodeField( name='Start Joint', value=start_joint, help_text='The ik spline start joint.') self.add_field(self.start_joint) self.end_joint = fields.MayaNodeField( name='End Joint', value=end_joint, help_text='The ik spline end joint.') self.add_field(self.end_joint) self.start_control = fields.MayaNodeField( name='Start Control', value=start_control, help_text='The control at the base of the spine.') self.add_field(self.start_control) self.end_control = fields.MayaNodeField( name='End Control', value=end_control, help_text='The control at the top of the spine.') self.add_field(self.end_control) self.system_name = fields.CharField( name='Name', value=name, help_text='The name of the system used with all the created nodes.' ) self.add_field(self.system_name)
class Component(core.Component): """A Component that creates aimConstraints.""" constraints = fields.ArrayField('constraints', add_label_text='Add Aim Constraint') container = fields.ContainerField('constraint', parent=constraints, container_view=AimConstraintView()) drivers = fields.MayaNodeField('drivers', multi=True, help_text='The nodes to aim at.', parent=container) driven = fields.MayaNodeField('driven', help_text='The node to aim', parent=container) maintain_offset = fields.BooleanField('maintain_offset', default=True, parent=container) aim_vector = fields.VectorField('aim_vector', default=(1.0, 0.0, 0.0), parent=container) up_vector = fields.VectorField('up_vector', default=(0.0, 1.0, 0.0), parent=container) world_up_type = fields.CharField( 'world_up_type', choices=['scene', 'object', 'objectrotation', 'vector', 'none'], default='object', parent=container) world_up_vector = fields.VectorField('world_up_vector', default=(0.0, 1.0, 0.0), parent=container) world_up_object = fields.MayaNodeField('world_up_object', parent=container) skip_x = fields.BooleanField('skip_x', parent=container) skip_y = fields.BooleanField('skip_y', parent=container) skip_z = fields.BooleanField('skip_z', parent=container) @classmethod def image_path(cls): return ':/aimConstraint.png' def execute(self): for container in self.constraints: drivers = container['drivers'].value() driven = container['driven'].value() skip = [ x for x in 'xyz' if container['skip_{0}'.format(x)].value() ] cmds.aimConstraint( drivers, driven, maintainOffset=container['maintain_offset'].value(), aimVector=container['aim_vector'].value(), upVector=container['up_vector'].value(), worldUpType=container['world_up_type'].value(), worldUpVector=container['world_up_vector'].value(), worldUpObject=container['world_up_object'].value(), skip=skip)
def add_constraint_data(self, constraint): container = fields.ContainerField( name='constraint', parent=self.constraints, container_view=ParentConstraintView()) fields.MayaNodeField(name='drivers', value=constraint.get('drivers', []), multi=True, help_text='The nodes to constrain to.', parent=container) fields.MayaNodeField(name='driven', value=constraint.get('driven', ''), help_text='The node to constrain.', parent=container) fields.BooleanField(name='maintain_offset', value=constraint.get('maintainOffset', True), parent=container) skip = constraint.get('skipTranslate', []) fields.BooleanField(name='skip_tx', verbose_name='Skip tx', value='x' in skip, parent=container) fields.BooleanField(name='skip_ty', verbose_name='Skip ty', value='y' in skip, parent=container) fields.BooleanField(name='skip_tz', verbose_name='Skip tz', value='z' in skip, parent=container) skip = constraint.get('skipRotate', []) fields.BooleanField(name='skip_rx', verbose_name='Skip rx', value='x' in skip, parent=container) fields.BooleanField(name='skip_ry', verbose_name='Skip ry', value='y' in skip, parent=container) fields.BooleanField(name='skip_rz', verbose_name='Skip rz', value='z' in skip, parent=container) return container
def add_constraint_data(self, constraint): container = fields.ContainerField( name='Constraint', orientation=fields.ContainerField.vertical, stretch=True) self.constraints.add_field(container) row_container = fields.ContainerField(name='', border=False) container.add_field(row_container) row_container.add_field( fields.MayaNodeField(name='Drivers', value=constraint.get('drivers', []), multi=True, help_text='The nodes to constrain to.')) row_container.add_field( fields.MayaNodeField(name='Driven', value=constraint.get('driven', ''), help_text='The node to constrain.')) row_container.add_field( fields.BooleanField(name='Maintain offset', value=constraint.get('maintainOffset', True))) skip = constraint.get('skipTranslate', []) row_container = fields.ContainerField(name='', border=False, stretch=True) container.add_field(row_container) row_container.add_field( fields.BooleanField(name='Skip tx', value='x' in skip)) row_container.add_field( fields.BooleanField(name='Skip ty', value='y' in skip)) row_container.add_field( fields.BooleanField(name='Skip tz', value='z' in skip)) skip = constraint.get('skipRotate', []) row_container.add_field( fields.BooleanField(name='Skip rx', value='x' in skip)) row_container.add_field( fields.BooleanField(name='Skip ry', value='y' in skip)) row_container.add_field( fields.BooleanField(name='Skip rz', value='z' in skip))
class Component(core.Component): """A Component that creates swingTwist nodes.""" twist_axis = { 0: 'X', 1: 'Y', 2: 'Z', } swingtwists = fields.ArrayField('swing_twists', add_label_text='Add SwingTwist', display_name=False) container = fields.ContainerField('swing_twist', parent=swingtwists, container_view=SwingTwistView()) driver = fields.MayaNodeField('driver', help_text='The node to drive the swingtwist', parent=container) driven = fields.MayaNodeField('driven', help_text='The node to be driven', parent=container) name = fields.CharField( 'name', default='swingTwist#', help_text='The name of the created swingTwist node.', parent=container) twist = fields.FloatField('twist', default=1.0, help_text='The twist amount', min_value=-1.0, max_value=1.0, parent=container) swing = fields.FloatField('swing', default=1.0, help_text='The swing amount', min_value=-1.0, max_value=1.0, parent=container) twist_axis = fields.CharField('twist_axis', default='X', choices=['X', 'Y', 'Z'], help_text='The twist axis', parent=container) @classmethod def image_path(cls): return shortcuts.get_icon_path('swingTwist') def execute(self): cmds.loadPlugin('cmt_py', qt=True) for container in self.swingtwists: driver = container['driver'].value() driven = container['driven'].value() if not cmds.objExists(driver) or not cmds.objExists(driven): logger.warning('{0} or {1} does not exist.'.format( driver, driven)) continue logger.info('Creating swingtwist on {0} from {1}'.format( driven, driver)) name = container['name'].value() twist = container['twist'].value() swing = container['swing'].value() twist_axis = 'XYZ'.index(container['twist_axis'].value()) cmds.swingTwist(driver, driven, name=name, twist=twist, swing=swing, twistAxis=twist_axis)
class Component(core.Component): """A Component that creates parentConstraints.""" constraints = fields.ArrayField('constraints', add_label_text='Add Parent Constraint') container = fields.ContainerField('constraint', parent=constraints, container_view=ParentConstraintView()) drivers = fields.MayaNodeField('drivers', multi=True, help_text='The nodes to constrain to.', parent=container) driven = fields.MayaNodeField('driven', help_text='The node to constrain.', parent=container) maintain_offset = fields.BooleanField('maintain_offset', default=True, parent=container) skip_tx = fields.BooleanField('skip_tx', verbose_name='Skip tx', parent=container) skip_ty = fields.BooleanField('skip_ty', verbose_name='Skip ty', parent=container) skip_tz = fields.BooleanField('skip_tz', verbose_name='Skip tz', parent=container) skip_rx = fields.BooleanField('skip_rx', verbose_name='Skip rx', parent=container) skip_ry = fields.BooleanField('skip_ry', verbose_name='Skip ry', parent=container) skip_rz = fields.BooleanField('skip_rz', verbose_name='Skip rz', parent=container) @classmethod def image_path(cls): return ':/parentConstraint.png' def add_constraint_data(self, constraint): container = fields.ContainerField( name='constraint', parent=self.constraints, container_view=ParentConstraintView()) fields.MayaNodeField(name='drivers', value=constraint.get('drivers', []), multi=True, help_text='The nodes to constrain to.', parent=container) fields.MayaNodeField(name='driven', value=constraint.get('driven', ''), help_text='The node to constrain.', parent=container) fields.BooleanField(name='maintain_offset', value=constraint.get('maintainOffset', True), parent=container) skip = constraint.get('skipTranslate', []) fields.BooleanField(name='skip_tx', verbose_name='Skip tx', value='x' in skip, parent=container) fields.BooleanField(name='skip_ty', verbose_name='Skip ty', value='y' in skip, parent=container) fields.BooleanField(name='skip_tz', verbose_name='Skip tz', value='z' in skip, parent=container) skip = constraint.get('skipRotate', []) fields.BooleanField(name='skip_rx', verbose_name='Skip rx', value='x' in skip, parent=container) fields.BooleanField(name='skip_ry', verbose_name='Skip ry', value='y' in skip, parent=container) fields.BooleanField(name='skip_rz', verbose_name='Skip rz', value='z' in skip, parent=container) return container def widget(self): widget = self.constraints.widget() # Add a new button to the widget button_layout to add selected constraints to the UI. button = QtWidgets.QPushButton('Add from Selected') button.released.connect( partial(self.add_from_selected, field_layout=widget.field_layout)) widget.button_layout.addWidget(button) return widget def add_from_selected(self, field_layout): # Get parentConstraints from the selected nodes sel = cmds.ls(sl=True) or [] constraints = [ x for x in sel if cmds.nodeType(x) == 'parentConstraint' ] transforms = [ x for x in sel if cmds.nodeType(x) in ['transform', 'joint'] ] for transform in transforms: constraints += (cmds.listConnections(transform, type='parentConstraint') or []) constraints = list(set(constraints)) for constraint in constraints: data = constraint_data(constraint) field = self.add_constraint_data(data) self.constraints.add_element( field, field_layout) # Update the UI with the added constraint def execute(self): for container in self.constraints: drivers = container['drivers'].value() driven = container['driven'].value() skip_translate = [ x for x in 'xyz' if container['skip_t{0}'.format(x)].value() ] skip_rotate = [ x for x in 'xyz' if container['skip_r{0}'.format(x)].value() ] cmds.parentConstraint( drivers, driven, maintainOffset=container['maintain_offset'].value(), skipTranslate=skip_translate, skipRotate=skip_rotate)
def __init__(self, constraints=None, **kwargs): """Constructor :param constraints: A list of dictionaries describing the aimConstraints that need to be created: { 'drivers': nodes, 'driven': node, 'maintainOffset': True, 'aimVector': (1.0, 0.0, 0.0), 'upVector': (0.0, 1.0, 0.0), 'worldUpType': "scene", "object", "objectrotation", "vector", or "none" 'worldUpVector': node, 'worldUpObject': node, 'skip': ['x', 'y', 'z'] } """ super(Component, self).__init__(**kwargs) self.constraints = fields.ArrayField( name='Aim Constraints', add_label_text='Add Aim Constraint') self.add_field(self.constraints) if not constraints: # Create default entries if none specified constraints = [{'driven': 'node'}] # The fields will be arranged in two row containers # [[driver, driven], [name, twist, swing, invertTwist, invertSwing, twistAxis]] for constraint in constraints: container = fields.ContainerField( name='Constraint', orientation=fields.ContainerField.vertical, stretch=True) self.constraints.add_field(container) row_container = fields.ContainerField(name='', border=False) container.add_field(row_container) row_container.add_field( fields.MayaNodeField(name='Drivers', value=constraint.get('drivers', []), multi=True, help_text='The nodes to aim at.')) row_container.add_field( fields.MayaNodeField(name='Driven', value=constraint.get('driven', ''), help_text='The node to aim')) row_container.add_field( fields.BooleanField(name='Maintain offset', value=constraint.get( 'maintainOffset', True))) row_container = fields.ContainerField(name='', border=False) container.add_field(row_container) row_container.add_field( fields.VectorField(name='Aim vector', value=constraint.get( 'aimVector', (1.0, 0.0, 0.0)))) row_container.add_field( fields.VectorField(name='Up vector', value=constraint.get( 'upVector', (0.0, 1.0, 0.0)))) row_container = fields.ContainerField(name='', border=False) container.add_field(row_container) choices = ['scene', 'object', 'objectrotation', 'vector', 'none'] row_container.add_field( fields.ChoiceField(name='World up type', choices=choices, value=constraint.get('worldUpType'))) row_container.add_field( fields.VectorField(name='World up vector', value=constraint.get( 'worldUpVector', (0.0, 1.0, 0.0)))) row_container.add_field( fields.MayaNodeField(name='World up object', value=constraint.get('worldUpObject', ''))) row_container = fields.ContainerField(name='', border=False, stretch=True) container.add_field(row_container) skip = constraint.get('skip', []) row_container.add_field( fields.BooleanField(name='Skip x', value='x' in skip)) row_container.add_field( fields.BooleanField(name='Skip y', value='y' in skip)) row_container.add_field( fields.BooleanField(name='Skip z', value='z' in skip))
def __init__(self, swing_twists=None, **kwargs): """Constructor :param swing_twists: A list of dictionaries describing the swingTwist nodes that need to be created: { 'driven': node, 'driver': nodes, 'name': name, 'twist': 1.0, 'swing': 0.2, } """ super(Component, self).__init__(**kwargs) self.swingtwists = fields.ArrayField(name='Swing Twists', add_label_text='Add SwingTwist') self.add_field(self.swingtwists) if not swing_twists: # Create default entries if none specified swing_twists = [{'name': 'swingTwist#'}] twist_axes = self.twist_axis.values() twist_axes.sort() # The fields will be arranged in two row containers # [[driver, driven], [name, twist, swing, invertTwist, invertSwing, twistAxis]] for swingtwist in swing_twists: container = fields.ContainerField( name='Swing Twist', orientation=fields.ContainerField.vertical, stretch=True) self.swingtwists.add_field(container) row_container = fields.ContainerField(name='', border=False) container.add_field(row_container) row_container.add_field( fields.MayaNodeField( name='Driver', value=swingtwist.get('driver', ''), help_text='The node to drive the swingtwist')) row_container.add_field( fields.MayaNodeField(name='Driven', value=swingtwist.get('driven', ''), help_text='The node to be driven')) row_container = fields.ContainerField(name='', border=False) container.add_field(row_container) row_container.add_field( fields.CharField( name='Name', value=swingtwist.get('name', 'swingTwist#'), help_text='The name of the created swingTwist node.')) row_container.add_field( fields.FloatField(name='Twist', value=swingtwist.get('twist', 1.0), help_text='The twist amount', min_value=-1.0, max_value=1.0)) row_container.add_field( fields.FloatField(name='Swing', value=swingtwist.get('swing', 1.0), help_text='The swing amount', min_value=-1.0, max_value=1.0)) row_container.add_field( fields.ChoiceField(name='Twist Axis', value=Component.twist_axis[swingtwist.get( 'twistAxis', 0)], choices=twist_axes, help_text='The twist axis'))