Example #1
0
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
Example #2
0
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)
Example #3
0
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)
Example #4
0
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    
Example #5
0
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
Example #6
0
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)