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