class LayerDataModel: log = getLogger("layerDataModel") # holds instance of singleton object __instance = None @staticmethod def getInstance(): ''' returns singleton instance of LayerDataModel :rtype: LayerDataModel ''' return LayerDataModel.__instance @classmethod def bindAll(cls): cls.__instance = LayerDataModel() MayaEvents.undoRedoExecuted.addHandler( cls.__instance.updateLayerAvailability) MayaEvents.nodeSelectionChanged.addHandler( cls.__instance.updateLayerAvailability) cls.__instance.updateLayerAvailability() def __init__(self): self.layerDataAvailable = None self.mll = MllInterface() self.clipboard = WeightsClipboard(self.mll) def setLayerListsUI(self, ui): self.layerListsUI = ui def getLayerListsUI(self): ''' :rtype: LayerListsUI ''' from ngSkinTools.ui import mainwindow mainWindow = mainwindow.MainWindow.getInstance() if mainWindow is None: return None return mainWindow.getLayersUI() def getSelectedLayer(self): listsUi = self.getLayerListsUI() if listsUi is None: return None return listsUi.getLayersList().getSelectedID() def getSelectedLayers(self): listsUi = self.getLayerListsUI() if listsUi is None: return [] return listsUi.getSelectedLayers() def getSelectedInfluenceIds(self): listsUi = self.getLayerListsUI() if listsUi is None: return [] return listsUi.getSelectedInfluenceIds() def updateLayerAvailability(self): ''' checks if availability of skin layers changed with the current scene selection ''' self.log.info("updating layer availability") oldValue = self.layerDataAvailable self.layerDataAvailable = self.mll.getLayersAvailable() if self.layerDataAvailable != oldValue: LayerEvents.layerAvailabilityChanged.emit() @Utils.undoable def addLayer(self, name): def guessParent(): currentLayer = self.mll.getCurrentLayer() if currentLayer is None: return None # guess layer's new parent parentsByLayerId = dict([ (layerId, parentId) for layerId, _, parentId in self.mll.listLayers() if currentLayer in (layerId, parentId) ]) # current layer is a parent? if currentLayer in parentsByLayerId.values(): return currentLayer # current layer has parent if currentLayer in parentsByLayerId.keys(): return parentsByLayerId[currentLayer] layerId = self.mll.createLayer(name) self.mll.setLayerParent(layerId, guessParent()) if layerId is None: return None LayerEvents.layerListModified.emit() self.setCurrentLayer(layerId) return layerId def removeLayer(self, layerId): self.mll.deleteLayer(layerId) LayerEvents.layerListModified.emit() LayerEvents.currentLayerChanged.emit() def setCurrentLayer(self, layerId): self.mll.setCurrentLayer(layerId) LayerEvents.currentLayerChanged.emit() def getCurrentLayer(self): return self.mll.getCurrentLayer() def attachLayerData(self): self.mll.initLayers() with self.mll.batchUpdateContext(): self.addLayer('Base Weights') self.updateLayerAvailability() selectionState.selectionInfo.dropCache() def cleanCustomNodes(self): ''' removes all custom nodes from current scene ''' # just in case we were in the middle of painting cmds.setToolTo('selectSuperContext') LayerUtils.deleteCustomNodes() # notify the rest of the world self.updateLayerAvailability() selectionState.selectionInfo.dropCache() def getLayerName(self, layerId): return mel.eval('ngSkinLayer -id {0} -q -name'.format(int(layerId))) def setLayerName(self, layerId, name): self.mll.setLayerName(layerId, name) LayerEvents.nameChanged.emit() def getLayerOpacity(self, layerId): return mel.eval('ngSkinLayer -id {0} -q -opacity'.format(layerId)) def getLayerEnabled(self, layerId): return mel.eval('ngSkinLayer -id {0} -q -enabled'.format(layerId)) def setLayerEnabled(self, layerId, enabled): cmds.ngSkinLayer(e=True, id=layerId, enabled=1 if enabled else 0) def toggleLayerEnabled(self, layerId): self.setLayerEnabled(layerId, not self.getLayerEnabled(layerId)) def getLayersCandidateFromSelection(self): ''' for given selection, returns mesh and skin cluster node names where skinLayer data is (or can be) attached. ''' return self.mll.getTargetInfo() def getLayersAvailable(self): self.updateLayerAvailability() return self.layerDataAvailable def isDqMode(self): ''' returns True if current skin cluster is operating in dual quaternion mode ''' target = self.mll.getTargetInfo() if not target: return False skinCluster = target[1] return cmds.skinCluster(skinCluster, q=True, skinMethod=True) == 2
class UseNgBrush(object): """ setup for custom brush operations, a new instance is created on every brush stroke """ def __init__(self, surface_name): self.surface = surface_name self.stroke_id = None self.mode = 1 self.value = 1 self.volumeThreshold = -0.1 self.mll = MllInterface() self.selection_name = cmds.ls(selection=True) self.mesh = cmds.listRelatives(self.selection_name[0], shapes=True) self.ngs_layer_id = self.mll.getCurrentLayer() self.ngs_influence = self.mll.getCurrentPaintTarget() self.ngs_weight_list = self.mll.getInfluenceWeights( self.ngs_layer_id, self.ngs_influence) self.max_value = max(self.ngs_weight_list) self.min_value = min(self.ngs_weight_list) def stroke_initialize(self): """ this function is executed before each brush stroke """ cmds.undoInfo(openChunk=True, undoName="paint stroke") get_stroke_id = ngLayerPaintCtxInitialize(self.mesh[0]) self.stroke_id = int(get_stroke_id.split(" ")[1]) cmds.ngSkinLayer(paintOperation=self.mode, paintIntensity=self.value) self.stroke_update() return self.surface, self.stroke_id def stroke_finalize(self): """ this function is executed after each brush stroke """ if self.stroke_id: cmds.ngLayerPaintCtxFinalize(self.stroke_id) self.stroke_id = None cmds.undoInfo(closeChunk=True) def stroke_update(self): """ updates certain attributes for the brush instance """ # self.mll = MllInterface() # self.selection_name = cmds.ls(selection=True) # self.mesh = cmds.listRelatives(self.selection_name[0], shapes=True) # self.ngs_layer_id = self.mll.getCurrentLayer() # self.ngs_influence = self.mll.getCurrentPaintTarget() # self.ngs_weight_list = self.mll.getInfluenceWeights(self.ngs_layer_id, self.ngs_influence) # self.max_value = max(self.ngs_weight_list) # self.min_value = min(self.ngs_weight_list) self.volumeThreshold = cmds.floatSlider("volume_slider", q=True, value=True) def contrast_paint(self, vert_id, value): """ sharpens the edge of the active weight map """ vertex_weight = self.ngs_weight_list[vert_id] if not self.max_value > vertex_weight > self.min_value: return avg_value = (self.max_value + self.min_value) / 2 normalized_range = self.max_value - self.min_value dist_value = vertex_weight - avg_value modifier = norm.cdf(dist_value, loc=0, scale=(0.1 * normalized_range)) - vertex_weight contrast_weight = vertex_weight + (modifier * value) contrast_weight = max(self.min_value, min(contrast_weight, self.max_value)) cmds.ngSkinLayer(paintIntensity=contrast_weight) cmds.ngLayerPaintCtxSetValue(self.stroke_id, vert_id, 1) def conceal_paint(self, vert_id, value): """ smooth operation that only lowers weight values """ vertex_weight = self.ngs_weight_list[vert_id] if vertex_weight <= self.min_value: return vertex_name = '{}.vtx[{}]'.format(self.selection_name[0], vert_id) area_vertices = get_surrounding_verts(vertex_name) weight_list = [self.ngs_weight_list[int(x)] for x in area_vertices] weight_avg = sum(weight_list) / float(len(weight_list)) min_avg = min(weight_list) threshold = 0.01 / (value / 0.1) if weight_avg >= self.max_value and abs(weight_avg - vertex_weight) <= threshold: return weight_diff = abs(weight_avg - vertex_weight) conceal_weight = vertex_weight * (1 - (weight_diff * value)) conceal_weight = max(conceal_weight, min_avg) cmds.ngSkinLayer(paintIntensity=conceal_weight) cmds.ngLayerPaintCtxSetValue(self.stroke_id, vert_id, 1) def spread_paint(self, vert_id, value): """ smooth operation that only increases weight values """ vertex_weight = self.ngs_weight_list[vert_id] if vertex_weight >= self.max_value: return vertex_name = '.'.join([self.selection_name[0], 'vtx[%d]' % vert_id]) area_vertices = get_surrounding_verts(vertex_name) weight_list = [self.ngs_weight_list[int(x)] for x in area_vertices] weight_avg = sum(weight_list) / float(len(weight_list)) max_avg = max(weight_list) threshold = 0.01 / (value / 0.1) if weight_avg <= self.min_value and abs(weight_avg - vertex_weight) <= threshold: return weight_diff = abs(weight_avg - vertex_weight) spread_weight = vertex_weight + (weight_diff * value) spread_weight = min(spread_weight, max_avg) cmds.ngSkinLayer(paintIntensity=spread_weight) cmds.ngLayerPaintCtxSetValue(self.stroke_id, vert_id, 1) def gain_paint(self, vert_id, value): """ increases existing weight values but preserves empty weights """ vertex_weight = self.ngs_weight_list[vert_id] if vertex_weight == 0: return gain_weight = vertex_weight + (vertex_weight * value) gain_weight = min(gain_weight, 1) cmds.ngSkinLayer(paintIntensity=gain_weight) cmds.ngLayerPaintCtxSetValue(self.stroke_id, vert_id, 1) def volume_equalize(self, vert_id, value): """ i.e a volumetric match operation with a falloff. applies weight values inside the brush radius onto other vertices inside a spherical volume """ origin_vertex = '.'.join([self.selection_name[0], 'vtx[%s]']) % vert_id vertex_weight = self.ngs_weight_list[vert_id] v1 = cmds.pointPosition(origin_vertex) for i in range(len(self.ngs_weight_list)): target_weight = self.ngs_weight_list[i] if target_weight == vertex_weight: continue if i == vert_id: continue target_vertex = '.'.join([self.selection_name[0], 'vtx[%s]']) % i v2 = cmds.pointPosition(target_vertex) target_distance = sqrt((pow((v1[0] - v2[0]), 2)) + (pow((v1[1] - v2[1]), 2)) + (pow((v1[2] - v2[2]), 2))) if target_distance > (self.volumeThreshold * value): continue falloff = (self.volumeThreshold - target_distance) / self.volumeThreshold eq_weight = target_weight - (( (target_weight - vertex_weight) * value) * falloff) cmds.ngSkinLayer(paintIntensity=eq_weight) cmds.ngLayerPaintCtxSetValue(self.stroke_id, i, 1)
class MapOperations(object): """ class that contains operations applied to the entire mesh """ def __init__(self): self.mll = MllInterface() self.selection_name = [] self.ngs_layer_id = -1 self.ngs_influence = None self.ngs_weight_list = [] self.ngs_vert_count = -1 self.max_value = -1.0 self.min_value = -1.0 def get_data(self): self.selection_name = cmds.ls(selection=True) self.ngs_layer_id = self.mll.getCurrentLayer() self.ngs_influence = self.mll.getCurrentPaintTarget() self.ngs_weight_list = self.mll.getInfluenceWeights( self.ngs_layer_id, self.ngs_influence) self.ngs_vert_count = self.mll.getVertCount() self.max_value = max(self.ngs_weight_list) self.min_value = min(self.ngs_weight_list) def grow_map(self, intensity): """ pushes the border of the active weight map outwards """ self.get_data() new_weight_list = [] for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if vertex_weight >= self.max_value: new_weight_list.append(vertex_weight) continue vertex_name = '.'.join([self.selection_name[0], 'vtx[%d]' % i]) area_vertices = get_surrounding_verts(vertex_name) weight_list = [self.ngs_weight_list[int(x)] for x in area_vertices] max_avg = max(weight_list) if max_avg <= self.min_value: new_weight_list.append(vertex_weight) continue grow_weight = vertex_weight + (abs(vertex_weight - max_avg) * intensity) grow_weight = min(grow_weight, self.max_value) new_weight_list.append(grow_weight) self.mll.setInfluenceWeights(self.ngs_layer_id, self.ngs_influence, new_weight_list) def shrink_map(self, intensity): """ pulls the border of the active weight map inwards """ self.get_data() new_weight_list = [] for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if vertex_weight <= self.min_value: new_weight_list.append(vertex_weight) continue vertex_name = '.'.join([self.selection_name[0], 'vtx[%d]' % i]) area_vertices = get_surrounding_verts(vertex_name) weight_list = [self.ngs_weight_list[int(x)] for x in area_vertices] min_avg = min(weight_list) if min_avg >= self.max_value: new_weight_list.append(vertex_weight) continue shrink_weight = vertex_weight - (abs(vertex_weight - min_avg) * intensity) shrink_weight = max(shrink_weight, self.min_value) new_weight_list.append(shrink_weight) self.mll.setInfluenceWeights(self.ngs_layer_id, self.ngs_influence, new_weight_list) def conceal_map(self, intensity): """ smooth operation for the active map by only lowering values """ self.get_data() new_weight_list = [] threshold = 0.01 / (intensity / 0.1) for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if vertex_weight <= self.min_value: new_weight_list.append(vertex_weight) continue vertex_name = '.'.join([self.selection_name[0], 'vtx[%d]' % i]) area_vertices = get_surrounding_verts(vertex_name) weight_list = [self.ngs_weight_list[int(x)] for x in area_vertices] weight_avg = sum(weight_list) / float(len(weight_list)) min_avg = min(weight_list) if weight_avg >= self.max_value and abs(weight_avg - vertex_weight) < threshold: new_weight_list.append(vertex_weight) continue weight_diff = abs(weight_avg - vertex_weight) conceal_weight = vertex_weight * (1 - (weight_diff * intensity)) conceal_weight = max(conceal_weight, min_avg) new_weight_list.append(conceal_weight) self.mll.setInfluenceWeights(self.ngs_layer_id, self.ngs_influence, new_weight_list) def spread_map(self, intensity): """ smooth operation for the active map by only increasing values """ self.get_data() new_weight_list = [] threshold = 0.01 / (intensity / 0.1) for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if vertex_weight >= self.max_value: new_weight_list.append(vertex_weight) continue vertex_name = '.'.join([self.selection_name[0], 'vtx[%d]' % i]) area_vertices = get_surrounding_verts(vertex_name) weight_list = [self.ngs_weight_list[int(x)] for x in area_vertices] weight_avg = sum(weight_list) / float(len(weight_list)) max_avg = max(weight_list) if weight_avg <= self.min_value and abs(weight_avg - vertex_weight) < threshold: new_weight_list.append(vertex_weight) continue weight_diff = abs(weight_avg - vertex_weight) spread_weight = vertex_weight + weight_diff * intensity spread_weight = min(spread_weight, max_avg) new_weight_list.append(spread_weight) self.mll.setInfluenceWeights(self.ngs_layer_id, self.ngs_influence, new_weight_list) def gain_map(self, intensity): """ 'reverse scale' tool that only increases weight values above 0 """ self.get_data() new_weight_list = [] for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if vertex_weight == 0: new_weight_list.append(vertex_weight) continue gain_weight = vertex_weight + (vertex_weight * intensity) gain_weight = min(gain_weight, 1) new_weight_list.append(gain_weight) self.mll.setInfluenceWeights(self.ngs_layer_id, self.ngs_influence, new_weight_list) def contrast_map(self, intensity): """ sharpens the edge of the active weight map """ self.get_data() new_weight_list = [] avg_value = (self.max_value + self.min_value) / 2 normalized_range = self.max_value - self.min_value for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if not self.max_value > vertex_weight > self.min_value: new_weight_list.append(vertex_weight) continue dist_value = vertex_weight - avg_value modifier = norm.cdf(dist_value, loc=0, scale=(0.1 * normalized_range)) - vertex_weight contrast_weight = vertex_weight + modifier * intensity contrast_weight = max(self.min_value, min(contrast_weight, self.max_value)) new_weight_list.append(contrast_weight) self.mll.setInfluenceWeights(self.ngs_layer_id, self.ngs_influence, new_weight_list)
class LayerDataModel: log = LoggerFactory.getLogger("layerDataModel") class MirrorCacheStatus: def __init__(self): self.isValid = None self.message = None self.mirrorAxis = None # holds instance of singleton object __instance = None @staticmethod def getInstance(): ''' returns singleton instance of LayerDataModel :rtype: LayerDataModel ''' if LayerDataModel.__instance is None: LayerDataModel.__instance = LayerDataModel() return LayerDataModel.__instance @staticmethod def reset(): LayerDataModel.__instance = None def __init__(self): self.layerListsUI = None # :type: LayerListsUI self.layerDataAvailable = None self.mirrorCache = self.MirrorCacheStatus() self.mll = MllInterface() self.clipboard = WeightsClipboard(self.mll) MayaEvents.undoRedoExecuted.addHandler(self.updateLayerAvailability) MayaEvents.nodeSelectionChanged.addHandler(self.updateLayerAvailability) self.updateLayerAvailability() def setLayerListsUI(self,ui): self.layerListsUI = ui def getSelectedLayer(self): if self.layerListsUI is None: return None return self.layerListsUI.getLayersList().getSelectedID() def updateLayerAvailability(self): ''' checks if availability of skin layers changed with the current scene selection ''' self.log.info("updating layer availability") oldValue = self.layerDataAvailable self.layerDataAvailable = self.mll.getLayersAvailable() if self.layerDataAvailable!=oldValue: LayerEvents.layerAvailabilityChanged.emit() self.updateMirrorCacheStatus() def updateMirrorCacheStatus(self): def setStatus(newStatus,message,axis=None): change = newStatus != self.mirrorCache.isValid or self.mirrorCache.message != message or self.mirrorCache.mirrorAxis != axis self.mirrorCache.message = message self.mirrorCache.isValid = newStatus self.mirrorCache.mirrorAxis = axis if change: self.log.info("mirror cache status changed to %s." % self.mirrorCache.message) LayerEvents.mirrorCacheStatusChanged.emit() self.log.info("updating mirror cache status") if not self.layerDataAvailable: setStatus(False,"Layer Data is not available") return try: cacheInfo = cmds.ngSkinLayer(q=True,mirrorCacheInfo=True) if cacheInfo[0]=='ok': setStatus(True,'Mirror Data Initialized',cmds.ngSkinLayer(q=True,mirrorAxis=True)) else: setStatus(False,cacheInfo[1]) except : setStatus(False,'Cache check failed') #log.error("error: "+str(err)) def addLayer(self,name): layerId = self.mll.createLayer(name) if layerId is None: return LayerEvents.layerListModified.emit() self.setCurrentLayer(layerId) def removeLayer(self,layerId): self.mll.deleteLayer(layerId) LayerEvents.layerListModified.emit() LayerEvents.currentLayerChanged.emit() def setCurrentLayer(self,layerId): self.mll.setCurrentLayer(layerId) LayerEvents.currentLayerChanged.emit() def getCurrentLayer(self): return self.mll.getCurrentLayer() def attachLayerData(self): self.mll.initLayers() self.addLayer('Base Weights') self.updateLayerAvailability() def cleanCustomNodes(self): ''' removes all custom nodes from current scene ''' LayerUtils.deleteCustomNodes() self.updateLayerAvailability() def getLayerName(self,layerId): return mel.eval('ngSkinLayer -id %d -q -name' % layerId) def setLayerName(self,layerId,name): self.mll.setLayerName(layerId,name) LayerEvents.nameChanged.emit() def getLayerOpacity(self,layerId): return mel.eval('ngSkinLayer -id %d -q -opacity' % layerId) def getLayerEnabled(self,layerId): return mel.eval('ngSkinLayer -id %d -q -enabled' % layerId) def setLayerEnabled(self,layerId,enabled): cmds.ngSkinLayer(e=True,id=layerId,enabled=1 if enabled else 0) def toggleLayerEnabled(self,layerId): self.setLayerEnabled(layerId, not self.getLayerEnabled(layerId)) def getLayersCandidateFromSelection(self): ''' for given selection, returns mesh and skin cluster node names where skinLayer data is (or can be) attached. ''' return self.mll.getTargetInfo() def getLayersAvailable(self): self.updateLayerAvailability() return self.layerDataAvailable def isDqMode(self): ''' returns True if current skin cluster is operating in dual quaternion mode ''' target = self.mll.getTargetInfo() if not target: return False skinCluster = target[1] return cmds.skinCluster(skinCluster,q=True,skinMethod=True)==2
class LayerDataModel: log = LoggerFactory.getLogger("layerDataModel") class MirrorCacheStatus: def __init__(self): self.isValid = None self.message = None self.mirrorAxis = None # holds instance of singleton object __instance = None @staticmethod def getInstance(): ''' returns singleton instance of LayerDataModel ''' if LayerDataModel.__instance is None: LayerDataModel.__instance = LayerDataModel() return LayerDataModel.__instance @staticmethod def reset(): LayerDataModel.__instance = None def __init__(self): self.layerListsUI = None self.layerDataAvailable = None self.mirrorCache = self.MirrorCacheStatus() self.mll = MllInterface() self.clipboard = WeightsClipboard(self.mll) MayaEvents.undoRedoExecuted.addHandler(self.updateLayerAvailability) MayaEvents.nodeSelectionChanged.addHandler( self.updateLayerAvailability) self.updateLayerAvailability() def setLayerListsUI(self, ui): self.layerListsUI = ui def getSelectedLayer(self): if self.layerListsUI is None: return None return self.layerListsUI.getLayersList().getSelectedID() def updateLayerAvailability(self): ''' updates interface visibility depending on availability of layer data ''' self.log.info("updating layer availability") oldValue = self.layerDataAvailable self.layerDataAvailable = self.mll.getLayersAvailable() if self.layerDataAvailable != oldValue: LayerEvents.layerAvailabilityChanged.emit() self.updateMirrorCacheStatus() def updateMirrorCacheStatus(self): def setStatus(newStatus, message, axis=None): change = newStatus != self.mirrorCache.isValid or self.mirrorCache.message != message or self.mirrorCache.mirrorAxis != axis self.mirrorCache.message = message self.mirrorCache.isValid = newStatus self.mirrorCache.mirrorAxis = axis if change: self.log.info("mirror cache status changed to %s." % self.mirrorCache.message) LayerEvents.mirrorCacheStatusChanged.emit() self.log.info("updating mirror cache status") if not self.layerDataAvailable: setStatus(False, "Layer Data is not available") return try: cacheInfo = cmds.ngSkinLayer(q=True, mirrorCacheInfo=True) if cacheInfo[0] == 'ok': setStatus(True, 'Mirror Data Initialized', cmds.ngSkinLayer(q=True, mirrorAxis=True)) else: setStatus(False, cacheInfo[1]) except: setStatus(False, 'Cache check failed') #log.error("error: "+str(err)) def addLayer(self, name): id = self.mll.createLayer(name) if id is None: return LayerEvents.layerListModified.emit() self.setCurrentLayer(id) def removeLayer(self, id): cmds.ngSkinLayer(rm=True, id=id) LayerEvents.layerListModified.emit() LayerEvents.currentLayerChanged.emit() def setCurrentLayer(self, id): cmds.ngSkinLayer(cl=id) LayerEvents.currentLayerChanged.emit() def getCurrentLayer(self): return self.mll.getCurrentLayer() return cmds.ngSkinLayer(q=True, cl=True) def attachLayerData(self): self.mll.initLayers() self.addLayer('Base Weights') self.updateLayerAvailability() def cleanCustomNodes(self): ''' removes all custom nodes from current scene ''' LayerUtils.deleteCustomNodes() self.updateLayerAvailability() def getLayerName(self, id): return mel.eval('ngSkinLayer -id %d -q -name' % id) def setLayerName(self, id, name): cmds.ngSkinLayer(e=True, id=id, name=name) LayerEvents.nameChanged.emit() def getLayerOpacity(self, id): return mel.eval('ngSkinLayer -id %d -q -opacity' % id) def getLayerEnabled(self, id): return mel.eval('ngSkinLayer -id %d -q -enabled' % id) def setLayerEnabled(self, id, enabled): cmds.ngSkinLayer(e=True, id=id, enabled=1 if enabled else 0) def toggleLayerEnabled(self, id): self.setLayerEnabled(id, not self.getLayerEnabled(id)) def getLayersCandidateFromSelection(self): ''' for given selection, returns mesh and skin cluster node names where skinLayer data is (or can be) attached. ''' try: return cmds.ngSkinLayer(q=True, ldt=True) except: return [] def getLayersAvailable(self): self.updateLayerAvailability() return self.layerDataAvailable
class Equalize(object): def __init__(self): self.mll = MllInterface() self.ngs_vert_count = -1 self.ngs_layer_id = -1 self.intensity = -1 self.ngs_influence = None self.vert_weight_dict = {} self.vert_weight_list = [] self.ngs_weight_dict = {} self.ngs_weight_list = [] self.new_weight_list = [] self.selection_vert = [] self.vertex_list = [] self.id_list = [] self.modes = { "max": self.vert_max, "min": self.vert_min, "avg": self.vert_avg, "first": self.vert_first, "last": self.vert_last } def get_data(self, check): self.ngs_weight_dict = {} self.vert_weight_dict = {} self.selection_vert = cmds.ls(os=True) if not self.selection_vert: return False if not check: self.ngs_influence = [("selected influence:", self.mll.getCurrentPaintTarget())] else: self.ngs_influence = self.mll.listLayerInfluences( layerId=None, activeInfluences=True) self.mll = MllInterface() self.ngs_layer_id = self.mll.getCurrentLayer() self.ngs_vert_count = self.mll.getVertCount() self.vertex_list = cmds.ls(self.selection_vert, flatten=True) self.id_list = list( map(lambda x: x[x.find("[") + 1:x.find("]")], self.vertex_list)) for influences in self.ngs_influence: influence_weights = self.mll.getInfluenceWeights( self.ngs_layer_id, influences[1]) vert_weights = [influence_weights[int(i)] for i in self.id_list] self.ngs_weight_dict[influences] = influence_weights self.vert_weight_dict[influences] = vert_weights return True def set_vert(self, mode, intensity): self.intensity = intensity for influences in self.ngs_influence: self.new_weight_list = [] self.ngs_weight_list = self.ngs_weight_dict[influences] self.vert_weight_list = self.vert_weight_dict[influences] self.modes[mode]() self.mll.setInfluenceWeights(self.ngs_layer_id, influences[1], self.new_weight_list) def vert_max(self): for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if str(i) not in self.id_list or vertex_weight == max( self.vert_weight_list): self.new_weight_list.append(vertex_weight) continue new_weight = vertex_weight + ( (max(self.vert_weight_list) - vertex_weight) * self.intensity) self.new_weight_list.append(new_weight) def vert_min(self): for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if str(i) not in self.id_list or vertex_weight == min( self.vert_weight_list): self.new_weight_list.append(vertex_weight) continue new_weight = vertex_weight - ( (vertex_weight - min(self.vert_weight_list)) * self.intensity) self.new_weight_list.append(new_weight) def vert_avg(self): average = sum(self.vert_weight_list) / float(len( self.vert_weight_list)) for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if str(i) not in self.id_list or vertex_weight == average: self.new_weight_list.append(vertex_weight) continue new_weight = vertex_weight - ( (vertex_weight - average) * self.intensity) self.new_weight_list.append(new_weight) def vert_first(self): first = self.vert_weight_list[0] for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if str(i) not in self.id_list or vertex_weight == first: self.new_weight_list.append(vertex_weight) continue new_weight = vertex_weight - ( (vertex_weight - first) * self.intensity) self.new_weight_list.append(new_weight) def vert_last(self): last = self.vert_weight_list[-1] for i in range(self.ngs_vert_count): vertex_weight = self.ngs_weight_list[i] if str(i) not in self.id_list or vertex_weight == last: self.new_weight_list.append(vertex_weight) continue new_weight = vertex_weight - ( (vertex_weight - last) * self.intensity) self.new_weight_list.append(new_weight)