コード例 #1
0
ファイル: tabSkinRelax.py プロジェクト: lazerdaze/lancer
#    of this source code package.
#    

from maya import cmds
from ngSkinTools.utils import Utils, MessageException
from ngSkinTools.ui.basetab import BaseTab
from ngSkinTools.ui.intensityslider import IntensitySlider
from ngSkinTools.doclink import SkinToolsDocs
from ngSkinTools.ui.uiWrappers import IntField, FloatField, CheckBoxField
from ngSkinTools.ui.softSelectionRow import SoftSelectionRow
from ngSkinTools.log import getLogger

     


log = getLogger("tabSkinRelax")
    
    

class TabSkinRelax(BaseTab):
    '''
        Defines a UI function set for Weights Relax operations.
    '''
    
    # prefix for environment variables for this tab
    VAR_RELAX_PREFIX = 'ngSkinToolsRelaxTab_'
    
     

    def __init__(self):
        BaseTab.__init__(self)
コード例 #2
0
class BaseTab(object):
    '''
    base class for ui group (tab) classes
    '''

    VAR_GROUP_COLLAPSE = 'ngSkinTools_group%s_collapse'

    log = getLogger("BaseToolWindow")

    def __init__(self):
        # create container for all controls.
        # using fake class instead of dictionary to simplify usage code
        self.controls = Controls()
        self.controls.groups = []
        self.parentWindow = None

        self.title = 'Untitled'

    def getTitle(self):
        '''
            return title of this gui set. 
            override for functionality
        '''
        return self.title

    def setTitle(self, title):
        self.title = title

    def getGroupVariable(self, group):
        title = cmds.frameLayout(group, q=True, label=True)
        title = title.replace(" ", "")
        return self.VAR_GROUP_COLLAPSE % title

    @staticmethod
    def createScrollLayout(parent):
        return cmds.scrollLayout(parent=parent, childResizable=True)

    def createUIGroup(self, layout, title, defaultCollapsed=False):
        '''
        creates collapsable UI group
        '''
        cmds.setParent(layout)

        group = uiWrappers.frameLayout(
            label=title,
            marginWidth=Constants.MARGIN_SPACING_HORIZONTAL,
            marginHeight=Constants.MARGIN_SPACING_VERTICAL,
            collapsable=True,
            expandCommand=self.saveOptions,
            collapseCommand=self.saveOptions)
        self.lastCreatedGroup = group

        self.controls.groups.append(group)
        cmds.frameLayout(group,
                         e=True,
                         collapse=Options.loadOption(
                             self.getGroupVariable(group),
                             1 if defaultCollapsed else 0))
        return cmds.columnLayout(adjustableColumn=1,
                                 rowSpacing=Constants.MARGIN_SPACING_VERTICAL)

    def createUI(self, parent):
        '''
        override this method to implement gui creation
        '''
        cmds.setParent(parent)
        self.baseLayout = cmds.columnLayout(
            rowSpacing=Constants.MARGIN_SPACING_VERTICAL, adjustableColumn=1)

    def saveOptions(self, *args):
        '''
        save gui options for this tab. this can be directly supplied as a handler to control's "change value" events
        '''
        for group in self.controls.groups:
            Options.saveOption(self.getGroupVariable(group),
                               cmds.frameLayout(group, q=True, collapse=True))

    @staticmethod
    def createHelpButton(helpLink):
        import os.path as path

        imageName = path.join(path.dirname(__file__), 'icons', 'help.png')

        return cmds.symbolButton('?',
                                 image=imageName,
                                 height=Constants.BUTTON_HEIGHT,
                                 width=Constants.BUTTON_WIDTH_SMALL,
                                 annotation='Open manual at: ' +
                                 helpLink.title,
                                 command=lambda *args: helpLink.open())

    @staticmethod
    def createTitledRow(parent,
                        title,
                        innerContentConstructor=None,
                        adjustable=True):
        return titledRow.create(
            parent,
            title,
            innerContentConstructor=innerContentConstructor,
            adjustable=adjustable)

    @staticmethod
    def createFixedTitledRow(parent, title):
        return titledRow.createFixed(parent, title)

    @staticmethod
    def layoutButtonForm(buttonForm, buttons):
        '''
        horizontally spaces buttons in a form with a grid size of 100
        '''
        for index, button in enumerate(buttons):
            spaceWidth = 100 / len(buttons)
            cmds.formLayout(buttonForm,
                            e=True,
                            attachForm=[(button, 'top', 0),
                                        (button, 'bottom', 0)],
                            attachPosition=[
                                (button, 'right',
                                 Constants.MARGIN_SPACING_HORIZONTAL / 2,
                                 spaceWidth * (index + 1)),
                                (button, 'left',
                                 Constants.MARGIN_SPACING_HORIZONTAL / 2,
                                 spaceWidth * index)
                            ])

    def createCommandLayout(self, commandIterator, helpLink):
        '''
        creates a layout that has a help button and command buttons at the bottom of the page, with a scroll layout created for the rest of the page;
        inside scroll layout, column layout is created for adding rows of interface
        
        
        commandIterator should be an iterator or a list of tuples with:
            * button label
            * button handler - either BaseAction action, or an executable object
        '''

        return CommandLayout(helpLink, commandIterator)
コード例 #3
0
from maya import cmds
from ngSkinTools.ui.basetab import BaseTab
from ngSkinTools.ui.editMirrorInfluencesWindow import EditMirrorInfluencesWindow
from ngSkinTools.ui.uiWrappers import FloatField, CheckBoxField, DropDownField
from ngSkinTools.doclink import SkinToolsDocs
from ngSkinTools.ui.layerDataModel import LayerDataModel
from ngSkinTools.ui.events import LayerEvents, MayaEvents
from ngSkinTools.log import getLogger
from ngSkinTools.orderedDict import OrderedDict
from ngSkinTools.ui.components.influencePrefixSuffixSelector import InfluencePrefixSuffixSelector
from ngSkinTools.ui.components import titledRow, uiGroup
from ngSkinTools.mllInterface import MllInterface, MirrorDirection
from ngSkinTools import selectionState
from ngSkinTools.influenceMapping import InfluenceMapping

log = getLogger("mirror UI")


class TabMirror(BaseTab):
    TOOL_PAINT = 'ngSkinToolsLayerPaintCtx'

    # prefix for environment variables for this tab
    VAR_PREFIX = 'ngSkinToolsMirrorTab_'

    def __init__(self):
        BaseTab.__init__(self)

    def executeMirror(self):
        self.influenceMappingConfiguration.updateSelectionsInfluenceMapping()

        mirrorDirection = MirrorDirection.DIRECTION_POSITIVETONEGATIVE
コード例 #4
0
#    of this source code package.
#

from maya import cmds
from ngSkinTools import selectionState
from ngSkinTools.doclink import SkinToolsDocs
from ngSkinTools.influenceMapping import InfluenceMapping
from ngSkinTools.log import getLogger
from ngSkinTools.mllInterface import MllInterface
from ngSkinTools.ui.basetab import CommandLayout
from ngSkinTools.ui.basetoolwindow import BaseToolWindow
from ngSkinTools.ui.components import uiGroup
from ngSkinTools.ui.components.influencesManualMapping import InfluencesManualMapping
from ngSkinTools.ui.components.influencesMappingPreview import InfluencesMappingPreview

log = getLogger('editMirrorInfluencesWindow')


class EditMirrorInfluencesWindow(BaseToolWindow):
    def __init__(self, windowName):
        BaseToolWindow.__init__(self, windowName)
        self.useUserPrefSize = False
        self.windowTitle = 'Edit Mirror Influences'
        self.sizeable = True
        self.defaultHeight = 400
        self.defaultWidth = 450

        self.influenceMappingPreview = InfluencesMappingPreview()
        self.influencesManualMapping = InfluencesManualMapping()

        self.buildMapper = None
コード例 #5
0
ファイル: layerUtils.py プロジェクト: lazerdaze/lancer
#        http://www.ngskintools.com
#
#    --------------------------------------------------------------------------
#
#    The coded instructions, statements, computer programs, and/or related
#    material (collectively the "Data") in these files are subject to the terms
#    and conditions defined by EULA.
#
#    A copy of EULA can be found in file 'LICENSE.txt', which is part
#    of this source code package.
#

from maya import cmds
from ngSkinTools.log import getLogger

log = getLogger("LayerUtils")


class NamedPaintTarget:
    MASK = "mask"
    DUAL_QUATERNION = "dq"


class LayerUtils:
    @staticmethod
    def iterCustomNodes():
        for nodeType in ['ngSkinLayerData', 'ngSkinLayerDisplay']:
            items = cmds.ls(type=nodeType)
            if items is not None:
                for i in items:
                    yield i
コード例 #6
0
ファイル: mllInterface.py プロジェクト: lazerdaze/lancer
 def __init__(self, mesh=None):
     self.log = log.getLogger("MllInterface")
     self.setCurrentMesh(mesh)
コード例 #7
0
ファイル: basetoolwindow.py プロジェクト: lazerdaze/lancer
class BaseToolWindow(object):
    log = getLogger("BaseToolWindow")
    
    windowInstances = {}
    
    def __init__(self,windowName):
        self.updateAvailable = False
        self.windowTitle = ''
        self.windowName = windowName
        self.sizeable = False
        self.menuBar = True
        
        self.defaultWidth = 300
        self.defaultHeight = 300
        self.useUserPrefSize = True
        
        BaseToolWindow.windowInstances[self.windowName]=self
        
    @staticmethod
    def closeAll():
        for _, window in BaseToolWindow.windowInstances.items():
            window.closeWindow()
        
    
    @staticmethod
    def getWindowInstance(windowName,windowClass=None):
        if BaseToolWindow.windowInstances.has_key(windowName):
            return BaseToolWindow.windowInstances[windowName]
        
        if windowClass is None:
            return None
        
        return BaseToolWindow.rebuildWindow(windowName, windowClass)
        
    @staticmethod
    def rebuildWindow(windowName,windowClass):
        BaseToolWindow.destroyWindow(windowName);
        instance = windowClass(windowName)
        instance.createWindow()
        return instance        
    
    def createWindow(self):
        self.log.debug("creating window "+self.windowName)
        if self.windowExists(self.windowName):
            raise Exception("window %s already opened" % self.windowName)
        if not self.useUserPrefSize:
            try:
                cmds.windowPref(self.windowName,remove=True)
                cmds.windowPref(self.windowName,width=self.defaultWidth,height=self.defaultHeight)
            except:
                pass

        cmds.window(self.windowName,
                                   title=self.windowTitle,
                                   maximizeButton=False,
                                   minimizeButton=False,
                                   width=self.defaultWidth,
                                   height=self.defaultHeight,
                                   sizeable=self.sizeable,
                                   menuBar=self.menuBar)
        
        
        scriptJobs.scriptJob(uiDeleted=[self.windowName,self.onWindowDeleted])
        
        HeadlessDataHost.HANDLE.addReference(self)
        
    def onWindowDeleted(self):
        if not HeadlessDataHost.HANDLE.removeReference(self):
            return

        BaseToolWindow.windowInstances.pop(self.windowName)
        
        
    def showWindow(self):
        if self.windowExists(self.windowName):
            cmds.showWindow(self.windowName)

    def closeWindow(self):
        if self.windowExists(self.windowName):
            self.onWindowDeleted()
            cmds.window(self.windowName,e=True,visible=False)

    @staticmethod        
    def windowExists(windowName):
        return cmds.window(windowName, exists=True)

    @staticmethod
    def destroyWindow(windowName):
        if BaseToolWindow.windowExists(windowName):
            instance = BaseToolWindow.getWindowInstance(windowName)
            if instance is not None:
                instance.onWindowDeleted();
            cmds.deleteUI(windowName, window=True)
            
    @staticmethod
    def closeAllWindows():
        for i in BaseToolWindow.windowInstances.values():
            i.closeWindow()
コード例 #8
0
ファイル: basedialog.py プロジェクト: lazerdaze/lancer
#    --------------------------------------------------------------------------
#
#    The coded instructions, statements, computer programs, and/or related
#    material (collectively the "Data") in these files are subject to the terms
#    and conditions defined by EULA.
#
#    A copy of EULA can be found in file 'LICENSE.txt', which is part
#    of this source code package.
#

from maya import cmds
from ngSkinTools.ui.uiWrappers import FormLayout
from ngSkinTools.ui.constants import Constants
from ngSkinTools.log import getLogger

log = getLogger("base dialog")


class Button:
    def __init__(self, title, buttonId):
        self.title = title
        self.buttonId = buttonId

    def __str__(self):
        return self.buttonId


class BaseDialog:
    currentDialog = None

    BUTTON_OK = Button("Ok", "ok")
コード例 #9
0
For usage details, see unit test examples.
'''

import re
from itertools import izip
import math
from maya import OpenMaya as om
from ngSkinTools.log import getLogger


def isChildOf(a, b):
    return b.startswith(a + "|")


log = getLogger("influenceMapping")


class NameMatchingRule:
    def __init__(self):
        self.prefixRegexp = None
        self.mirrorMode = False
        self.prefixes = None
        self.ignoreNamespaces = True

        self.reversePathCache = {}

    def reversePath(self, path):
        cachedResult = self.reversePathCache.get(path)
        if cachedResult is not None:
            return cachedResult
コード例 #10
0
ファイル: utils.py プロジェクト: lazerdaze/lancer
from maya import OpenMaya as om
from maya import cmds
from maya import mel
from ngSkinTools.log import getLogger
from functools import wraps


class MessageException(Exception):
    def __init__(self, message):
        self.message = message

    def __str__(self, *args, **kwargs):
        return self.message


log = getLogger("utils")


def confirmDialog(**kwargs):
    '''
    used to be a pre-2011 Maya compatibility wrapper
    of cmds.confirmDialog. Keeping for now
    '''

    return cmds.confirmDialog(**kwargs)


def displayError(message):
    '''
    displays error in script editor and in a dialog box
    '''
コード例 #11
0
#    A copy of EULA can be found in file 'LICENSE.txt', which is part
#    of this source code package.
#

import os
from maya import cmds
from ngSkinTools.license import fileFormat
from ngSkinTools.log import getLogger
from ngSkinTools.ui.events import Signal

from ngSkinTools.ui.options import PersistentValueModel
from ngSkinTools.utils import Utils

savedLicensePath = PersistentValueModel("ngSkinToolsOption_licensePath")

log = getLogger("license")


class LicenseType:
    RLM = "rlm-ez"
    NGSTKEY = "ngstKey"


class Status:
    '''
    given licensePath, track license status.
    works both with ngstKey licenses and RLM licenses
    '''
    def __init__(self):
        '''
        :param str licensePath:
コード例 #12
0
ファイル: weightsClipboard.py プロジェクト: lazerdaze/lancer
#
#    --------------------------------------------------------------------------
#
#    The coded instructions, statements, computer programs, and/or related
#    material (collectively the "Data") in these files are subject to the terms
#    and conditions defined by EULA.
#
#    A copy of EULA can be found in file 'LICENSE.txt', which is part
#    of this source code package.
#

from ngSkinTools.utils import MessageException
from ngSkinTools.log import getLogger
from ngSkinTools.layerUtils import NamedPaintTarget

log = getLogger("WeightsClipboard")


class WeightsClipboard:
    def __init__(self, mllInterface):
        '''
        :param MllInterface mllInterface: 
        '''
        self.copiedWeights = None
        self.mll = mllInterface
        self.layer = None
        self.influence = None

    def withCurrentLayerAndInfluence(self):
        '''
        :rtype: WeightsClipboard
コード例 #13
0
from maya import cmds
from ngSkinTools import selectionState
from ngSkinTools.selectionState import selectionInfo
from ngSkinTools.ui.uiWrappers import FormLayout, TextEdit, RadioButtonField
from ngSkinTools.ui.constants import Constants
from ngSkinTools.layerUtils import NamedPaintTarget
from ngSkinTools.ui.layerDataModel import LayerDataModel
from ngSkinTools.ui.events import LayerEvents, Signal, MayaEvents
from ngSkinTools.utils import Utils
from ngSkinTools.ui.options import Options, PersistentValueModel
from ngSkinTools.log import getLogger
from ngSkinTools.InfluenceNameTransforms import InfluenceNameTransform
from ngSkinTools.InfluenceNameFilter import InfluenceNameFilter
from ngSkinTools.ui import uiWrappers

log = getLogger("layerListsUI")


class IdToNameEntry(object):
    def __init__(self, itemId=None, name=None, displayName=None, suffix=None):
        assert isinstance(itemId, basestring)

        if displayName is None:
            displayName = name

        self.id = itemId

        self.name = name
        self.displayName = displayName
        self.suffix = suffix
        self.parent = None
コード例 #14
0
ファイル: events.py プロジェクト: lazerdaze/lancer
#    
#    --------------------------------------------------------------------------
#
#    The coded instructions, statements, computer programs, and/or related
#    material (collectively the "Data") in these files are subject to the terms 
#    and conditions defined by EULA.
#         
#    A copy of EULA can be found in file 'LICENSE.txt', which is part 
#    of this source code package.
#    

from maya import cmds
from ngSkinTools.log import getLogger


log = getLogger("events")

class Signal:
    '''
    Signal class collects observers, interested in some particular event,and handles
    signaling them all when some event occurs. Both handling and signaling happens outside
    of signal's own code
    '''

    all = []

    def __init__(self,name):
        if name is None:
            raise Exception("need name for debug purposes later")
        self.name = name
        self.reset()
コード例 #15
0
#
#    The coded instructions, statements, computer programs, and/or related
#    material (collectively the "Data") in these files are subject to the terms 
#    and conditions defined by EULA.
#         
#    A copy of EULA can be found in file 'LICENSE.txt', which is part 
#    of this source code package.
#    

from ngSkinTools.mllInterface import MllInterface
from ngSkinTools.utils import MessageException
from ngSkinTools.log import getLogger
from maya import cmds
from ngSkinTools.skinClusterFn import SkinClusterFn

log = getLogger("ImportInfluences")

class ImportInfluences(object):

    def __init__(self):
        self.sourceSkinCluster = None
        self.destinationSkinCluster = None
        
        
    def __detectSkinCluster(self,mesh):
        mll = MllInterface()
        mll.setCurrentMesh(mesh)
        try:
            _,skinCluster = mll.getTargetInfo()
        except TypeError:
            raise MessageException("cannot find skin cluster attached to %s" % mesh)
コード例 #16
0
ファイル: headlessDataHost.py プロジェクト: lazerdaze/lancer
#    The coded instructions, statements, computer programs, and/or related
#    material (collectively the "Data") in these files are subject to the terms
#    and conditions defined by EULA.
#
#    A copy of EULA can be found in file 'LICENSE.txt', which is part
#    of this source code package.
#

from ngSkinTools import selectionState
from ngSkinTools.ui.layerDataModel import LayerDataModel
from ngSkinTools.utils import Utils
from ngSkinTools.ui.events import MayaEvents, scriptJobs
from ngSkinTools.doclink import SkinToolsDocs
from ngSkinTools.log import getLogger

log = getLogger("HeadlessDataHost")


class RefCountedHandle:
    '''
    reference counted handle to a dynamically allocated instance;
    
    creates reference after first addReference() call, and destroys it 
    when last reference is removed via removeReference()
    '''
    def __init__(self, instantiator):
        self.instantiator = instantiator
        self.instance = None
        self.references = set()

    def getCurrentInstance(self):
コード例 #17
0
ファイル: tabPaint.py プロジェクト: lazerdaze/lancer
from ngSkinTools.ui.components import titledRow
from ngSkinTools.ui.mainwindow import MainWindow
from ngSkinTools.utils import Utils
from ngSkinTools.ui.events import LayerEvents, MayaEvents
from ngSkinTools.ui.layerDataModel import LayerDataModel
from ngSkinTools.ui.uiWrappers import RadioButtonField, DropDownField,\
    CheckBoxField
from ngSkinTools.doclink import SkinToolsDocs
from ngSkinTools.ui.options import PersistentValueModel
from ngSkinTools.ui.uiCompounds import FloatSliderField
from ngSkinTools.ui.SelectHelper import SelectHelper
from ngSkinTools.mllInterface import PaintMode, MllInterface
from ngSkinTools.paint import ngLayerPaintCtxInitialize
from ngSkinTools.log import getLogger

log = getLogger("tabPaint")


class TabPaint(BaseTab):
    TOOL_PAINT = 'ngSkinToolsLayerPaintCtx'

    VAR_PREFIX = 'ngSkinToolsPaintTab_'

    def __init__(self):
        BaseTab.__init__(self)

        self.parentWindow = None  # type: MainWindow

        self.controls.brushShapeButtons = []

        self.intensityReplace = PersistentValueModel(self.VAR_PREFIX +
コード例 #18
0
from ngSkinTools.doclink import SkinToolsDocs
from ngSkinTools.ui.components import uiGroup
from ngSkinTools.ui.components.influencesManualMapping import InfluencesManualMapping
from ngSkinTools.ui.components.influencesMappingPreview import InfluencesMappingPreview
from ngSkinTools.ui.events import LayerEvents, MayaEvents
from ngSkinTools.ui.uiWrappers import FloatField, StoredTextEdit,\
    DropDownField, CheckBoxField, RadioButtonField
from ngSkinTools.ui.layerDataModel import LayerDataModel
from ngSkinTools.ui.constants import Constants
from ngSkinTools.utils import Utils
from ngSkinTools.log import getLogger
from ngSkinTools.influenceMapping import InfluenceMapping
from ngSkinTools.mllInterface import MllInterface
from ngSkinTools.orderedDict import OrderedDict

log = getLogger("initTransferWindow")


class CopyWeightsModel(object):
    vertexTransferModes = OrderedDict((
        ("Closest point on surface", "closestPoint"),
        ("UV space", "uvSpace"),
        ("By Vertex ID", "vertexId"),
    ))

    def __init__(self):
        self.parent = None
        self.sourceModel = None
        self.sourceMesh = None
        self.targetMesh = None
コード例 #19
0
ファイル: layerDataModel.py プロジェクト: lazerdaze/lancer
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
コード例 #20
0
class TransferWeightsTab(BaseTab):
    log = getLogger("Transfer Weights Tab")
    VAR_PREFIX = 'ngSkinToolsTransferTab_'

    axisValues = ('X', 'Y', 'Z')

    def __init__(self):
        BaseTab.__init__(self)
        self.dataModel = CopyWeightsModel()
        self.dataModel.parent = self
        self.currentSelection = None

        self.influenceMappingPreview = InfluencesMappingPreview()
        self.influencesManualMapping = InfluencesManualMapping()

    def createUI(self, parent):
        buttons = [('Done', self.execContinue, ''),
                   ('Cancel', self.closeWindow, '')]

        self.cmdLayout = self.createCommandLayout(
            buttons, SkinToolsDocs.INITWEIGHTTRANSFER_INTERFACE)

        self.createTransferOptionsGroup()
        self.createInfluenceMappingGroup()

        LayerEvents.layerAvailabilityChanged.addHandler(
            self.updateLayoutEnabled, self.cmdLayout.outerLayout)
        MayaEvents.nodeSelectionChanged.addHandler(self.updateUIValues,
                                                   self.cmdLayout.outerLayout)

        self.updateLayoutEnabled()
        self.updateUIValues()
        self.updatePreferedValues()

    def releaseUI(self):
        LayerEvents.layerAvailabilityChanged.removeHandler(
            self.updateLayoutEnabled)
        MayaEvents.nodeSelectionChanged.removeHandler(self.updateUIValues)

    def updatePreferedValues(self):
        self.influencesManualMapping.manualOverrides = {}

    def updateUIValues(self):
        # when selection changes between update UI calls, overwrite UI with preferred values in the mesh
        selection = cmds.ls(sl=True)
        if selection != self.currentSelection:
            self.updatePreferedValues()
        self.currentSelection = selection
        self.previewInfluenceMapping()

    def createTransferOptionsGroup(self):
        group = self.createUIGroup(self.cmdLayout.innerLayout,
                                   'Transfer Options')
        self.createTitledRow(parent=group, title="Vertex Transfer Mode")
        self.controls.transferMode = DropDownField(self.VAR_PREFIX +
                                                   'vertexTransferMode')

        for opt in CopyWeightsModel.vertexTransferModes.keys():
            self.controls.transferMode.addOption(opt)

        self.createTitledRow(parent=group, title=None)
        self.controls.keepExistingLayers = CheckBoxField(
            self.VAR_PREFIX + 'KeepExistingLayers',
            label="Keep existing layers",
            annotation=
            'when unselected, will delete existing layers in destination',
            defaultValue=1)

    def createInfluenceMappingGroup(self):
        group = self.createUIGroup(self.cmdLayout.innerLayout,
                                   'Influence Mapping')

        self.createFixedTitledRow(group, 'Infl. Distance Error')
        self.controls.influenceDistanceError = FloatField(
            self.VAR_PREFIX + 'distanceError',
            minValue=0,
            maxValue=None,
            step=0.01,
            defaultValue=0.001,
            annotation=
            'Defines maximum inaccuracy between left and right influence positions'
        )
        self.controls.influenceDistanceError.changeCommand.addHandler(
            self.previewInfluenceMapping, group)

        self.createTitledRow(parent=group, title="Namespaces")
        self.controls.ignoreNamespaces = CheckBoxField(
            self.VAR_PREFIX + 'IgnoreNamespaces',
            label="Ignore",
            annotation='ignore influence namespaces when matching by name',
            defaultValue=1)
        self.controls.ignoreNamespaces.changeCommand.addHandler(
            self.previewInfluenceMapping, ownerUI=group)

        self.influenceMappingPreview.mirrorMode = False
        self.influenceMappingPreview.createUI(parent=group)
        self.influenceMappingPreview.onDelete.addHandler(
            self.influencesManualMapping.removeSelectedManualMappings, group)

        manualGroup = uiGroup.create(self.cmdLayout.innerLayout,
                                     'Manual influence mapping')
        self.influencesManualMapping.mirrorMode = False
        self.influencesManualMapping.createUI(parent=manualGroup)
        self.influencesManualMapping.getSelectedInfluences = lambda: self.influenceMappingPreview.currentInfluencesSelection
        self.influencesManualMapping.manualOverridesChanged.addHandler(
            self.previewInfluenceMapping, group)

        cmds.setParent(group)

    def closeWindow(self, *args):
        self.parentWindow.closeWindow()

    def buildInfluenceMappingEngine(self):
        '''
        :rtype: InfluenceMapping
        '''
        result = self.dataModel.buildInfluenceMappingEngine(self.controls)
        result.manualOverrides = self.influencesManualMapping.manualOverrides
        return result

    def previewInfluenceMapping(self):
        if not self.dataModel.isEnabled():
            return
        engine = self.buildInfluenceMappingEngine()
        engine.calculate()
        self.influenceMappingPreview.mapper = engine
        self.influenceMappingPreview.constructInfluenceList()

    def execContinue(self, *args):
        self.previewInfluenceMapping()
        self.dataModel.execute()
        self.closeWindow()

    def updateLayoutEnabled(self):
        '''
        updates UI enabled/disabled flag based on layer data availability
        '''
        enabled = self.dataModel.isEnabled()
        cmds.layout(self.cmdLayout.innerLayout, e=True, enable=enabled)
        cmds.layout(self.cmdLayout.buttonForm, e=True, enable=enabled)
コード例 #21
0
ファイル: actions.py プロジェクト: lazerdaze/lancer
from __future__ import with_statement
from maya import cmds, mel
from ngSkinTools import utils
from ngSkinTools.ui.events import Signal, LayerEvents, MayaEvents
from ngSkinTools.ui.layerDataModel import LayerDataModel
from ngSkinTools.ui.dlgLayerProperties import LayerPropertiesDialog
from ngSkinTools.ui.basedialog import BaseDialog
from ngSkinTools.utils import Utils, MessageException
from ngSkinTools.ui.basetoolwindow import BaseToolWindow
from ngSkinTools.log import getLogger
from ngSkinTools.ui.options import deleteCustomOptions
from ngSkinTools.mllInterface import MllInterface, MirrorDirection
from ngSkinTools.ui import tabMirror

log = getLogger("actions")


class BaseAction(object):
    def __init__(self, ownerUI):
        self.ownerUI = ownerUI
        self.onExecuted = Signal("action executed")
        self.updateControls = []

    def addUpdateControl(self, control, menu=False):
        self.updateControls.append((control, menu))

    def isEnabled(self):
        '''
        override this method to provide enabled/disabled state of this action
        '''
コード例 #22
0
#    The coded instructions, statements, computer programs, and/or related
#    material (collectively the "Data") in these files are subject to the terms
#    and conditions defined by EULA.
#
#    A copy of EULA can be found in file 'LICENSE.txt', which is part
#    of this source code package.
#
'''
Cached information about current selection
'''
from ngSkinTools.log import getLogger
from ngSkinTools.mllInterface import MllInterface
from ngSkinTools.stateStore import CachedValue
from ngSkinTools.ui.events import Signal, LayerEvents, MayaEvents

log = getLogger('selectionState')

mll = MllInterface()

# container for mirror related state
mirrorInfo = CachedValue('mirrorInfo', lambda: {
    'axis': mll.getMirrorAxis(),
})

# container for primary selection data
selectionInfo = CachedValue(
    'selectionInfo', lambda: {
        'target': mll.getTargetInfo(),
        'layersAvailable': mll.getLayersAvailable(),
    })