def _create_twist_joints(self):
        """
        Internal function that creates twist joints
        """

        distance = dcc.distance_between_nodes(self._twist_driver,
                                              self._twist_driven)
        distance_ratio = distance / (self._twist_joints_count - 1)
        twist_axis = self._get_twist_axis()

        root_node = dcc.node_parent(self._twist_driver, full_path=False)
        if root_node == dcc.node_short_name(self._twist_driven):
            twist_axis = (mathlib.Vector(*twist_axis) * -1.0).list()

        for i in range(self._twist_joints_count):
            dcc.clear_selection()
            twist_joint = dcc.create_joint(self._get_name('roll',
                                                          id=i,
                                                          node_type='joint'),
                                           size=self._scale)
            dcc.match_rotation(self._twist_joint or self._twist_driver,
                               twist_joint)
            dcc.match_translation(self._twist_driver, twist_joint)
            joint_utils.OrientJointAttributes.zero_orient_joint(twist_joint)
            if self._reverse_orient:
                twist_joint = dcc.set_parent(twist_joint, self._twist_driven)
            else:
                twist_joint = dcc.set_parent(twist_joint, self._twist_driver)

            new_distance = mathlib.Vector(*twist_axis) * (distance_ratio * i)
            dcc.translate_node_in_object_space(twist_joint,
                                               new_distance.list(),
                                               relative=True)
            self._twist_joints.append(twist_joint)
Ejemplo n.º 2
0
    def set_curve_type(self, type_name=None, keep_color=True, **kwargs):
        """
        Updates the curves of the control with the given control type
        :param type_name: str
        :param keep_color: bool
        """

        color = kwargs.get('color', None)
        control_size = kwargs.get('control_size', 1.0)
        auto_scale = kwargs.get('auto_scale', True)
        auto_scale = auto_scale if control_size is None else False
        axis = kwargs.pop('axis', None)
        if axis:
            kwargs['axis_order'] = self.axis_map.get(axis, None)
        if color:
            keep_color = False
        control_type = kwargs.pop('control_type', 'circle')
        kwargs['control_type'] = type_name or control_type
        kwargs['keep_color'] = keep_color
        kwargs['auto_scale'] = auto_scale
        kwargs['parent'] = self._name

        new_control = controllib.replace_control_curves(self._name, **kwargs)

        dcc.clear_selection()

        return new_control
Ejemplo n.º 3
0
 def _create_rivet(self):
     if self._create_joint:
         dcc.clear_selection()
         self._rivet = dcc.create_joint(
             name=dcc.find_unique_name('joint_{}'.format(self._name)))
     else:
         self._rivet = dcc.create_locator(
             name=dcc.find_unique_name('rivet_{}'.format(self._name)))
    def create(self):
        dcc.clear_selection()

        self._create_groups()
        self._create_nurbs_plane()
        self._create_follicles()
        self._create_joints()
        self._create_connector_controls()
        self._create_blendshape_setup()
        self._create_wire_setup()
        self._connect_clusters_to_controls()
        self._create_twist_setup()
        self._create_squash_stretch_setup()
Ejemplo n.º 5
0
    def _before_load(self, clear_selection=True):
        """
        Internal function that is called before loading the pose
        :param clear_selection:
        """

        logger.debug('Before Load Pose "{}"'.format(self.path))

        if not self._is_loading:
            self._is_loading = True
            dcc.enable_undo()
            self._selection = dcc.selected_nodes() or list()
            self._auto_key_frame = dcc.is_auto_keyframe_enabled()
            dcc.set_auto_keyframe_enabled(False)
            if clear_selection:
                dcc.clear_selection()
Ejemplo n.º 6
0
    def _import_skin_weights(self, data_path, mesh):
        if not dcc.node_exists(mesh) or not os.path.isdir(data_path):
            return False

        try:
            if not dcc.is_plugin_loaded('ngSkinTools2'):
                dcc.load_plugin('ngSkinTools2')
            import ngSkinTools2
            from ngSkinTools2 import api as ngst_api
        except ImportError:
            logger.warning(
                'NgSkinTools 2.0 is not installed. Impossible to import ngSkin data'
            )
            return False

        ng_skin_data_path = path_utils.join_path(data_path, 'ngdata.json')
        if not path_utils.is_file(ng_skin_data_path):
            logger.warning(
                'No Ng Skin Data file found: "{}", aborting import skin weights operation ...'
                .format(ng_skin_data_path))
            return False

        is_valid_mesh = False
        shape_types = ['mesh', 'nurbsSurface', 'nurbsCurve', 'lattice']
        for shape_type in shape_types:
            if shape_utils.has_shape_of_type(mesh, shape_type):
                is_valid_mesh = True
                break
        if not is_valid_mesh:
            logger.warning(
                'Node "{}" is not a valid mesh node! Currently supported nodes include: {}'
                .format(mesh, shape_types))
            return False

        logger.info('Importing skin clusters {} --> "{}"'.format(
            mesh, data_path))

        influence_dict = self._get_influences(data_path)
        if not influence_dict:
            logger.warning('No influences data found for: {}'.format(mesh))
            return False

        influences = influence_dict.keys()
        if not influences:
            logger.warning('No influences found for: "{}"'.format(mesh))
            return False
        influences.sort()
        logger.debug('Influences found for {}: {}'.format(mesh, influences))

        short_name = dcc.node_short_name(mesh)
        transfer_mesh = None

        if shape_utils.has_shape_of_type(mesh, 'mesh'):
            orig_mesh = self._import_mesh_obj(data_path)
            if orig_mesh:
                mesh_match = geo_utils.is_mesh_compatible(orig_mesh, mesh)
                if not mesh_match:
                    transfer_mesh = mesh
                    mesh = orig_mesh
                else:
                    dcc.delete_node(orig_mesh)

        # Check if there are duplicated influences and also for the creation of influences that does not currently
        # in the scene
        add_joints = list()
        remove_entries = list()
        for influence in influences:
            joints = dcc.list_nodes(influence, full_path=True)
            if type(joints) == list and len(joints) > 1:
                add_joints.append(joints[0])
                conflicting_count = len(joints)
                logger.warning(
                    'Found {} joints with name {}. Using only the first one: {}'
                    .format(conflicting_count, influence, joints[0]))
                remove_entries.append(influence)
                influence = joints[0]
            if not dcc.node_exists(influence):
                dcc.clear_selection()
                dcc.create_joint(
                    name=influence,
                    position=influence_dict[influence]['position'])
        for entry in remove_entries:
            influences.remove(entry)
        influences += add_joints

        settings_data = dict()
        settings_path = path_utils.join_path(data_path, 'settings.info')
        if path_utils.is_file(settings_path):
            lines = fileio.get_file_lines(settings_path)
            for line in lines:
                test_line = line.strip()
                if not test_line:
                    continue
                line_list = eval(line)
                attr_name = line_list[0]
                value = line_list[1]
                settings_data[attr_name] = value

        # Create skin cluster and removes if it already exists
        skin_cluster = deform_utils.find_deformer_by_type(mesh, 'skinCluster')
        if skin_cluster:
            dcc.delete_node(skin_cluster)

        skin_node_name = settings_data.pop('skinNodeName',
                                           'skin_{}'.format(short_name))
        skin_cluster = maya.cmds.skinCluster(
            influences, mesh, tsb=True,
            n=dcc.find_unique_name(skin_node_name))[0]
        dcc.set_attribute_value(skin_cluster, 'normalizeWeights', 0)
        skin_utils.set_skin_weights_to_zero(skin_cluster)

        # TODO: This Influence mapping configuration should be generated during export and imported here as JSON file
        # Import ng skin data
        config = ngst_api.InfluenceMappingConfig()
        config.use_distance_matching = True
        config.use_label_matching = True
        config.use_name_matching = True

        ngst_api.import_json(mesh,
                             file=ng_skin_data_path,
                             influences_mapping_config=config)

        maya.cmds.skinCluster(skin_cluster, edit=True, normalizeWeights=1)
        maya.cmds.skinCluster(skin_cluster,
                              edit=True,
                              forceNormalizeWeights=True)

        for attr_name, value in settings_data.items():
            if attr_name == 'blendWeights':
                skin_utils.set_skin_blend_weights(skin_cluster, value)
            else:
                if dcc.attribute_exists(skin_cluster, attr_name):
                    dcc.set_attribute_value(skin_cluster, attr_name, value)

        if transfer_mesh:
            logger.info(
                'Import sking weights: mesh topology does not match. Trying to transfer topology ...'
            )
            skin_utils.skin_mesh_from_mesh(mesh, transfer_mesh)
            dcc.delete_node(mesh)

        logger.info('Import skinCluster weights: {} from {}'.format(
            short_name, data_path))

        return True
 def _create_joints(self):
     for i in range(len(self._follicles)):
         dcc.clear_selection()
         self._joints.append(dcc.create_joint(name=self._get_name('joint', id=i, node_type='joint')))
         dcc.match_translation(self._follicles[i], self._joints[i])
         dcc.set_parent(self._joints[i], self._follicles[i])