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 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))