diff --git a/DRAG_AND_DROP_INSTALL.py b/DRAG_AND_DROP_INSTALL.py index dc613da..a8e79fa 100644 --- a/DRAG_AND_DROP_INSTALL.py +++ b/DRAG_AND_DROP_INSTALL.py @@ -5,8 +5,8 @@ from GETOOLS_SOURCE.values import Icons -from GETOOLS_SOURCE.utils import Shelf from GETOOLS_SOURCE.utils import Install +from GETOOLS_SOURCE.utils import Shelf # Get script directory path diff --git a/GETOOLS_SOURCE/_deprecated/OVERLAPPY.py b/GETOOLS_SOURCE/_deprecated/OVERLAPPY.py deleted file mode 100644 index 81a353f..0000000 --- a/GETOOLS_SOURCE/_deprecated/OVERLAPPY.py +++ /dev/null @@ -1,1094 +0,0 @@ -### DEPRECATED ### -# Copyright 2023 by Eugene Gataulin (GenEugene). All Rights Reserved. - -# Overlappy v2.0.0 for Maya 2022 -# Author Eugene Gataulin (GenEugene) tek94@mail.ru tek942@gmail.com -# https://github.com/GenEugene/Overlappy - -import maya.cmds as c -from math import pow, sqrt -from functools import partial -# import maya.mel as mel -# import sys, os - -class OVLP: - # NAMING - textTitle = "OVERLAPPY v2.0.0" - nameWindowMain = "__OverlappyWindow__" - nameGroup = "_OverlappyGroup_" - nameLocGoalTarget = ("_locGoal_", "_locTarget_") - nameLocAim = ("_locAimBase_", "_locAimHidden_", "_locAim_", "_locAimUp_") - nameParticle = "_particle_" - nameLoft = ("_loftStart_", "_loftEnd_", "_loftShape_") - nameLayers = ("_OVLP_BASE_", "_OVLP_SAFE_", "OVLP_", "OVLPpos_", "OVLProt_") - nameBakedWorldLocator = "BakedWorldLocator_" - replaceSymbols = ("_R1S_", "_R2S_") # for "|" and ":" - # WINDOW - windowWidth = 330 - windowHeight = 27 - lineHeight = 28 - sliderWidth = (60, 60, 10) - markerWidth = 6 - # LOFT - loftFactor = 0.9 - loftMinDistance = 5 - # SIMULATION SETTINGS # TODO: move to preset - checkboxesOptions = [False, True, False, True] - particleRadius = 20 - particleConserve = 1 - particleDrag = 0.01 - particleDamp = 0 - goalSmooth = 3 - goalWeight = 0.5 - nucleusTimeScale = 1 - loopOffset = 2 # TODO set count of pre cycles - # SLIDERS (field min/max, slider min/max) - rangePRadius = (0, float("inf"), 0, 50) - rangePConserve = (0, 1, 0, 1) - rangePDrag = (0, 10, 0, 1) - rangePDamp = (0, 10, 0, 1) - rangeGSmooth = (0, 100, 0, 10) - rangeGWeight = (0, 1, 0, 1) - rangeNTimeScale = (0.001, 100, 0.001, 4) - rangeOffsetX = (float("-inf"), float("inf"), 0, 300) - rangeOffsetY = (float("-inf"), float("inf"), 0, 300) - rangeOffsetZ = (float("-inf"), float("inf"), 0, 300) - # COLORS - cLRed = (1, .7, .7) - cRed = (1, .5, .5) - cLOrange = (1, .75, .45) - cOrange = (1, .6, .3) - cYellow = (1, 1, .5) - cGreen = (.6, 1, .6) - cLBlue = (.5, .9, 1) - cBlue = (.3, .7, 1) - cPurple = (.81, .4, 1) - cWhite = (1, 1, 1) - cGray = (.5, .5, .5) - cDarkGray = (.3, .3, .3) - cBlack = (.15, .15, .15) - # CONSTANTS - attributesT = ("tx", "ty", "tz") - attributesR = ("rx", "ry", "rz") - attributesS = ("sx", "sy", "sz") - constraintsNames = ("parentConstraint", "pointConstraint", "orientConstraint", "scaleConstraint", "aimConstraint") - - ### MAIN - def __init__(self): - # VALUES - self.time = [0, 0, 0, 0, 0] # current, minS, min, max, maxE - self.startPositionGoalParticle = [None, (0, 0, 0)] - # OBJECTS - self.selected = "" - self.locGoalTarget = ["", ""] - self.locAim = ["", "", "", ""] - self.particle = "" - self.nucleus = "" - self.loft = ["", "", ""] - self.layers = ["", ""] - # LAYOUTS - self.windowMain = None - self.layoutMain = None - self.layoutButtons = None - # self.layoutBaking = None - # self.layoutOptions = None - self.layoutSimulation = None - self.layoutOffset = None - self.layoutDevTools = None - # CHECKBOXES - self.checkboxHierarchy = None - self.checkboxLayer = None - self.checkboxLoop = None - self.checkboxClean = None - self.checkboxMirrorX = None - self.checkboxMirrorY = None - self.checkboxMirrorZ = None - # SLIDERS - self.sliderPRadius = None - self.sliderPConserve = None - self.sliderPDrag = None - self.sliderPDamp = None - self.sliderGSmooth = None - self.sliderGWeight = None - self.sliderNTimeScale = None - self.sliderOffsetX = None - self.sliderOffsetY = None - self.sliderOffsetZ = None - def CreateUI(self): - # WINDOW - if c.window(OVLP.nameWindowMain, exists = True): - c.deleteUI(OVLP.nameWindowMain) - self.windowMain = c.window(OVLP.nameWindowMain, title = OVLP.textTitle, maximizeButton = 0, sizeable = 0, resizeToFitChildren = True, widthHeight = (OVLP.windowWidth, OVLP.windowHeight * 6)) - self.layoutMain = c.columnLayout(adjustableColumn = True, height = OVLP.windowHeight) - - # CLASSES - class classCheckbox: - def __init__(self, label="label", value=False, command="pass", menuReset=True, enabled=True, ccResetAll="pass"): - self.value = value - self.checkbox = c.checkBox(label = label, value = value, changeCommand = command, enable = enabled) - c.popupMenu() - if (menuReset): - c.menuItem(label = "reset current", command = self.Reset) - c.menuItem(label = "reset all", command = ccResetAll) - def Get(self, *args): - return c.checkBox(self.checkbox, query = True, value = True) - def Set(self, value=None, *args): - c.checkBox(self.checkbox, edit = True, value = value) - def Reset(self, *args): - c.checkBox(self.checkbox, edit = True, value = self.value) - class classSlider: - def __init__(self, label="label", attribute="", startName="", nameAdd=True, value=0, minMax=[0, 1, 0, 1], parent=self.layoutMain, command="pass", precision=3, menuReset=True, menuScan=True, ccResetAll="pass", ccScanAll="pass"): - self.attribute = attribute - self.startName = startName - self.addSelectedName = nameAdd - self.value = value - self.command = command - self.precision = precision - self.markerColorDefault = OVLP.cGray - self.markerColorChanged = OVLP.cBlue - self.valueCached = 0; - c.flowLayout(parent = parent) - self.slider = c.floatSliderGrp(label = " " + label, value = self.value, changeCommand = self.command, dragCommand = self.command, fieldMinValue = minMax[0], fieldMaxValue = minMax[1], minValue = minMax[2], maxValue = minMax[3], field = True, - precision = self.precision, width = OVLP.windowWidth - OVLP.markerWidth, columnAlign = (1, "left"), columnWidth3 = (OVLP.sliderWidth[0], OVLP.sliderWidth[1], OVLP.sliderWidth[2]), enableKeyboardFocus = True) - c.popupMenu(parent = self.slider) - if (menuReset): - c.menuItem(label = "reset current", command = self.Reset) - c.menuItem(label = "reset all", command = ccResetAll) - if (menuScan): - c.menuItem(divider = True) - c.menuItem(label = "scan current", command = self.Scan) - c.menuItem(label = "scan all", command = ccScanAll) - self._marker = c.button(label = "", enable = 0, w = OVLP.markerWidth, backgroundColor = self.markerColorDefault) - def Get(self, *args): - return c.floatSliderGrp(self.slider, query = True, value = True) - def Set(self, value=None, *args): - if (value == None): _value = c.floatSliderGrp(self.slider, query = True, value = True) - else: - _value = value - c.floatSliderGrp(self.slider, edit = True, value = _value) - self.command() - # Marker update - if (_value != self.value): - c.button(self._marker, edit = True, backgroundColor = self.markerColorChanged) - else: - c.button(self._marker, edit = True, backgroundColor = self.markerColorDefault) - # Check selected - _selectedName = _OVERLAPPY.selected - if (_selectedName == ""): - return - # Add suffix or not - _selectedName = _OVERLAPPY.ConvertText(_selectedName) # TODO _OVERLAPPY - if (self.addSelectedName): - _selectedName = self.startName + _selectedName - else: - _selectedName = self.startName - # Set attribute - try: - c.setAttr(_selectedName + self.attribute, _value) - except: - # print("Can't set value") - pass - def Reset(self, *args): - c.button(self._marker, edit = True, backgroundColor = self.markerColorDefault) - c.floatSliderGrp(self.slider, edit = True, value = self.value) - self.command() - def Scan(self, *args): - _firstName = _OVERLAPPY.selected - if (_firstName == ""): - return - _firstName = _OVERLAPPY.ConvertText(_firstName) - if (self.addSelectedName): - _firstName = self.startName + _firstName - else: - _firstName = self.startName - # Get attribute - try: - # print(firstName + self._attribute) - _value = c.getAttr(_firstName + self.attribute) - c.floatSliderGrp(self.slider, edit = True, value = _value) - except: - # print("Can't get value") - return - # Marker update - if (round(_value, 3) != self.value): - c.button(self._marker, edit = True, backgroundColor = self.markerColorChanged) - else: - c.button(self._marker, edit = True, backgroundColor = self.markerColorDefault) - def GetCached(self, *args): - return self.valueCached - def SetCached(self, *args): - self.valueCached = c.floatSliderGrp(self.slider, query = True, value = True) - def ResetCached(self, *args): - self.valueCached = 0 - - # HEAD MENU - c.menuBarLayout() - # - # c.menu(label = "Settings") - # c.menuItem(label = "Save") - # c.menuItem(label = "Save as") - # c.menuItem(label = "Load") - # c.menuItem(divider = True) - # c.menuItem(label = "Reset") - # - c.menu(label = "Scene") - c.menuItem(label = "Reload", command = self.SceneReload) - c.menuItem(dividerLabel = "Be careful", divider = True) - c.menuItem(label = "Quit", command = self.SceneQuit) - # - c.menu(label = "Script") - c.menuItem(label = "Reload", command = self.Restart) - c.menuItem(dividerLabel = "Layouts", divider = True) - c.menuItem(label = "Collapse all", command = partial(self.LayoutsCollapseLogic, True)) - c.menuItem(label = "Expand all", command = partial(self.LayoutsCollapseLogic, False)) - c.menuItem(dividerLabel = "Other", divider = True) - c.menuItem(label = "Dev Tools toggle", command = self.LayoutDevToolsToggle, checkBox = False) - # - c.menu(label = "Help") - def LinkPatreon(self): c.showHelp("https://www.patreon.com/geneugene", absolute = True) - def LinkGumroad(self): c.showHelp("https://app.gumroad.com/geneugene", absolute = True) - def LinkGithub(self): c.showHelp("https://github.com/GenEugene/Overlappy", absolute = True) - def LinkYoutube(self): c.showHelp("https://www.youtube.com/channel/UCCIzdVu6RMqUoOmxHoOEPAQ", absolute = True) - def LinkReport(self): c.showHelp("https://github.com/GenEugene/Overlappy/discussions/categories/report-a-problem", absolute = True) - c.menuItem(label = "About Overlappy", enable = False) # TODO add window with information - c.menuItem(dividerLabel = "Links", divider = True) - # c.menuItem(label = "Discord") - c.menuItem(label = "Patreon", command = LinkPatreon) - c.menuItem(label = "Gumroad", command = LinkGumroad) - c.menuItem(label = "GitHub", command = LinkGithub) - c.menuItem(label = "YouTube", command = LinkYoutube) - c.menuItem(dividerLabel = "Support", divider = True) - c.menuItem(label = "Report a Problem...", command = LinkReport) - - # BUTTONS - self.layoutButtons = c.frameLayout(label = "BUTTONS", parent = self.layoutMain, collapseCommand = self.Resize_UI, expandCommand = self.Resize_UI, collapsable = True, borderVisible = True, backgroundColor = OVLP.cBlack) - c.gridLayout(parent = self.layoutButtons, numberOfColumns = 4, cellWidthHeight = (OVLP.windowWidth / 4, OVLP.lineHeight)) - c.button(label = "RESET ALL", command = self._ResetAllValues, backgroundColor = OVLP.cYellow) - c.button(label = "SELECT", command = self.SelectTransformHierarchy, backgroundColor = OVLP.cLBlue) - c.popupMenu() - c.menuItem(dividerLabel = "Created objects", divider = True) - c.menuItem(label = "Objects", command = self._SelectObjects) - c.menuItem(label = "Particle", command = self._SelectParticle) - c.menuItem(label = "Nucleus", command = self._SelectNucleus) - c.menuItem(label = "Target", command = self._SelectTarget) - c.menuItem(label = "Aim", command = self._SelectAim) - c.button(label = "LAYERS", command = partial(self._LayerMoveToSafeOrBase, True), backgroundColor = OVLP.cBlue) # _LayerCreate_TEST - old func for tests - c.popupMenu() - c.menuItem(dividerLabel = "Move", divider = True) - c.menuItem(label = "Move to Base layer", command = partial(self._LayerMoveToSafeOrBase, False)) - c.menuItem(dividerLabel = "Delete", divider = True) - c.menuItem(label = "Delete '{0}'".format(OVLP.nameLayers[0]), command = partial(self._LayerDelete, OVLP.nameLayers[0])) - c.menuItem(label = "Delete '{0}'".format(OVLP.nameLayers[1]), command = partial(self._LayerDelete, OVLP.nameLayers[1])) - c.menuItem(divider = True) - c.menuItem(label = "Delete 'BaseAnimation'", command = partial(self._LayerDelete, "BaseAnimation")) - c.button(label = "SETUP", command = self._SetupInit, backgroundColor = OVLP.cGreen) - c.popupMenu() - c.menuItem(label = "Scan setup into scene", command = self._SetupScan) - c.menuItem(dividerLabel = "Delete", divider = True) - c.menuItem(label = "Delete setup", command = self._SetupDelete) - - # BAKING - # self.layoutBaking = c.frameLayout(label = "BAKING", parent = self.layoutMain, collapseCommand = self.Resize_UI, expandCommand = self.Resize_UI, collapsable = True, borderVisible = True, backgroundColor = OVLP.cBlack) - # c.gridLayout(parent = self.layoutButtons, numberOfColumns = 4, cellWidthHeight = (OVLP.windowWidth / 4, OVLP.lineHeight)) - c.button(label = "TRANSLATION", command = partial(self._BakeVariants, 1), backgroundColor = OVLP.cLOrange) - c.popupMenu() - c.menuItem(label = "use offset", command = partial(self._BakeVariants, 2)) - c.button(label = "ROTATION", command = partial(self._BakeVariants, 3), backgroundColor = OVLP.cLOrange) - c.button(label = "COMBO", command = partial(self._BakeVariants, 4), backgroundColor = OVLP.cLOrange) - c.popupMenu() - c.menuItem(label = "translate + rotate", command = self._BakeVariantComboTR) - c.menuItem(label = "rotate + translate", command = self._BakeVariantComboRT) - # c.gridLayout(parent = self.layoutBaking, numberOfColumns = 2, cellWidthHeight = (OVLP.windowWidth / 2, OVLP.lineHeight)) - c.button(label = "TO LOCATOR", command = self._BakeWorldLocator, backgroundColor = OVLP.cOrange) - - # OPTIONS - # self.layoutOptions = c.frameLayout(label = "OPTIONS", parent = self.layoutMain, collapseCommand = self.Resize_UI, expandCommand = self.Resize_UI, collapsable = True, borderVisible = True, backgroundColor = OVLP.cBlack) - # c.gridLayout(parent = self.layoutButtons, numberOfColumns = 4, cellWidthHeight = (OVLP.windowWidth / 4, OVLP.lineHeight)) - _optionsResetAll = self._ResetOptions - self.checkboxHierarchy = classCheckbox(label = "HIERARCHY", value = OVLP.checkboxesOptions[0], menuReset = True, ccResetAll = _optionsResetAll) - self.checkboxLayer = classCheckbox(label = "LAYER", value = OVLP.checkboxesOptions[1], menuReset = True, ccResetAll = _optionsResetAll) - self.checkboxLoop = classCheckbox(label = "LOOP", value = OVLP.checkboxesOptions[2], menuReset = True, ccResetAll = _optionsResetAll) - self.checkboxClean = classCheckbox(label = "CLEAN", value = OVLP.checkboxesOptions[3], menuReset = True, ccResetAll = _optionsResetAll) - - # SIMULATION SETTINGS - self.layoutSimulation = c.frameLayout(label = "SIMULATION", parent = self.layoutMain, collapseCommand = self.Resize_UI, expandCommand = self.Resize_UI, collapsable = True, borderVisible = True, backgroundColor = OVLP.cBlack) - c.columnLayout(parent = self.layoutSimulation) - _simStartName = OVLP.nameParticle - _simParent = self.layoutSimulation - _simCCDefault = self._ValuesSetSimulation - _simCCReset = partial(self._ResetSimulation, True) - _simCCGetValues = self._GetSimulation - self.sliderPRadius = classSlider(label = "Radius", attribute = "Shape.radius", startName = _simStartName, nameAdd = True, value = OVLP.particleRadius, minMax = OVLP.rangePRadius, parent = _simParent, command = _simCCDefault, ccResetAll = _simCCReset, ccScanAll = _simCCGetValues) - self.sliderPConserve = classSlider(label = "Conserve", attribute = "Shape.conserve", startName = _simStartName, nameAdd = True, value = OVLP.particleConserve, minMax = OVLP.rangePConserve, parent = _simParent, command = _simCCDefault, ccResetAll = _simCCReset, ccScanAll = _simCCGetValues) - self.sliderPDrag = classSlider(label = "Drag", attribute = "Shape.drag", startName = _simStartName, nameAdd = True, value = OVLP.particleDrag, minMax = OVLP.rangePDrag, parent = _simParent, command = _simCCDefault, ccResetAll = _simCCReset, ccScanAll = _simCCGetValues) - self.sliderPDamp = classSlider(label = "Damp", attribute = "Shape.damp", startName = _simStartName, nameAdd = True, value = OVLP.particleDamp, minMax = OVLP.rangePDamp, parent = _simParent, command = _simCCDefault, ccResetAll = _simCCReset, ccScanAll = _simCCGetValues) - self.sliderGSmooth = classSlider(label = "G.Smooth", attribute = "Shape.goalSmoothness", startName = _simStartName, nameAdd = True, value = OVLP.goalSmooth, minMax = OVLP.rangeGSmooth, parent = _simParent, command = _simCCDefault, ccResetAll = _simCCReset, ccScanAll = _simCCGetValues) - self.sliderGWeight = classSlider(label = "G.Weight", attribute = "Shape.goalWeight[0]", startName = _simStartName, nameAdd = True, value = OVLP.goalWeight, minMax = OVLP.rangeGWeight, parent = _simParent, command = _simCCDefault, ccResetAll = _simCCReset, ccScanAll = _simCCGetValues) - self.sliderNTimeScale = classSlider(label = "Time Scale", attribute = ".timeScale", startName = self.nucleus, nameAdd = False, value = OVLP.nucleusTimeScale, minMax = OVLP.rangeNTimeScale, parent = _simParent, command = _simCCDefault, ccResetAll = _simCCReset, ccScanAll = _simCCGetValues) - - # OFFSET SETTINGS - self.layoutOffset = c.frameLayout(label = "OFFSET", parent = self.layoutMain, collapseCommand = self.Resize_UI, expandCommand = self.Resize_UI, collapsable = True, borderVisible = True, backgroundColor = OVLP.cBlack) - c.gridLayout(numberOfColumns = 4, cellWidthHeight = (OVLP.windowWidth / 4, OVLP.lineHeight)) - c.separator() - self.checkboxMirrorX = classCheckbox(label = "MIRROR X", command = partial(self._OffsetsUpdate, True), menuReset = True, enabled = True, ccResetAll = self._ResetOffsets) - self.checkboxMirrorY = classCheckbox(label = "MIRROR Y", command = partial(self._OffsetsUpdate, True), menuReset = True, enabled = True, ccResetAll = self._ResetOffsets) - self.checkboxMirrorZ = classCheckbox(label = "MIRROR Z", command = partial(self._OffsetsUpdate, True), menuReset = True, enabled = True, ccResetAll = self._ResetOffsets) - c.columnLayout(parent = self.layoutOffset) - _offStartName = OVLP.nameLocGoalTarget[0] - _offParent = self.layoutOffset - _offCCDefault = self._OffsetsUpdate - _offCCReset = self._ResetOffsets - _offCCGetValues = self._GetOffsets - self.sliderOffsetX = classSlider(label = " Local X", attribute = "_parentConstraint1.target[0].targetOffsetTranslateX", startName = _offStartName, minMax = OVLP.rangeOffsetX, parent = _offParent, command = _offCCDefault, ccResetAll = _offCCReset, ccScanAll = _offCCGetValues) - self.sliderOffsetY = classSlider(label = " Local Y", attribute = "_parentConstraint1.target[0].targetOffsetTranslateY", startName = _offStartName, minMax = OVLP.rangeOffsetY, parent = _offParent, command = _offCCDefault, ccResetAll = _offCCReset, ccScanAll = _offCCGetValues) - self.sliderOffsetZ = classSlider(label = " Local Z", attribute = "_parentConstraint1.target[0].targetOffsetTranslateZ", startName = _offStartName, minMax = OVLP.rangeOffsetZ, parent = _offParent, command = _offCCDefault, ccResetAll = _offCCReset, ccScanAll = _offCCGetValues) - - # DEV TOOLS - self.layoutDevTools = c.frameLayout(label = "DEV TOOLS", parent = self.layoutMain, collapseCommand = self.Resize_UI, expandCommand = self.Resize_UI, collapsable = True, borderVisible = True, backgroundColor = OVLP.cBlack, visible = False) - c.gridLayout(parent = self.layoutDevTools, numberOfColumns = 3, cellWidthHeight = (OVLP.windowWidth / 3, OVLP.lineHeight)) - c.button(label = "DEV FUNCTION", command = self._DEVFunction, backgroundColor = OVLP.cBlack) - c.button(label = "MOTION TRAIL", command = self._MotionTrailCreate, backgroundColor = OVLP.cBlack) - c.popupMenu() - c.menuItem(label = "Select", command = self._MotionTrailSelect) - c.menuItem(divider = True) - c.menuItem(label = "Delete", command = self._MotionTrailDelete) - - # RUN WINDOW - c.showWindow(self.windowMain) - self.Resize_UI() - def Resize_UI(self, *args): # TODO get count of visible layouts - c.window(self.windowMain, edit = True, height = 152, resizeToFitChildren = True) # OVLP.windowHeight * 6 - - def LayoutsCollapseLogic(self, value, *args): # TODO to external class - if (value): - if (self.LayoutsCollapseCheck() == value): - return - else: - if (self.LayoutsCollapseCheck() == value): - return - c.frameLayout(self.layoutButtons, edit = True, collapse = value) - # c.frameLayout(self.layoutBaking, edit = True, collapse = value) - # c.frameLayout(self.layoutOptions, edit = True, collapse = value) - c.frameLayout(self.layoutSimulation, edit = True, collapse = value) - c.frameLayout(self.layoutOffset, edit = True, collapse = value) - c.frameLayout(self.layoutDevTools, edit = True, collapse = value) - self.Resize_UI() - def LayoutsCollapseCheck(self, *args): # needed to fix the window bug - check1 = c.frameLayout(self.layoutButtons, query = True, collapse = True) - # check2 = c.frameLayout(self.layoutBaking, query = True, collapse = True) - # check3 = c.frameLayout(self.layoutOptions, query = True, collapse = True) - check4 = c.frameLayout(self.layoutSimulation, query = True, collapse = True) - check5 = c.frameLayout(self.layoutOffset, query = True, collapse = True) - check6 = c.frameLayout(self.layoutDevTools, query = True, collapse = True) - # if (check1 == check2 == check3 == check4 == check5 == check6): - if (check1 == check4 == check5 == check6): - return check1 - def LayoutDevToolsToggle(self, *args): - _value = c.frameLayout(self.layoutDevTools, query = True, visible = True) - c.frameLayout(self.layoutDevTools, edit = True, visible = not _value) - self.Resize_UI() - - def SceneReload(self, *args): # TODO to external class - currentScene = c.file(query = True, sceneName = True) - if(currentScene): c.file(currentScene, open = True, force = True) - else: c.file(new = True, force = True) - def SceneQuit(self, *args): # TODO to external class - c.quit(force = True) - - def ConvertText(self, text, direction=True, *args): - if (direction): - _text = text.replace("|", OVLP.replaceSymbols[0]) - _text = _text.replace(":", OVLP.replaceSymbols[1]) - return _text - else: - _text = text.replace(OVLP.replaceSymbols[0], "|") - _text = _text.replace(OVLP.replaceSymbols[1], ":") - return _text - - def TimeRangeScan(self, *args): # TODO to external class - self.time[0] = c.currentTime(query = True) - self.time[1] = c.playbackOptions(query = True, animationStartTime = True) - self.time[2] = c.playbackOptions(query = True, min = True) - self.time[3] = c.playbackOptions(query = True, max = True) - self.time[4] = c.playbackOptions(query = True, animationEndTime = True) - def TimeRangeSetCurrent(self, value, *args): - c.currentTime(value) - def TimeRangeSetCurrentCached(self, *args): - c.currentTime(self.time[0]) - def TimeRangeSetMin(self, value, *args): - c.playbackOptions(edit = True, min = value) - def TimeRangeReset(self, *args): - c.playbackOptions(edit = True, animationStartTime = self.time[1], min = self.time[2], max = self.time[3], animationEndTime = self.time[4]) - c.currentTime(self.time[2]) - - def SelectTransformHierarchy(self, *args):# TODO from GETools class (need to merge in future) - _selected = c.ls(selection = True) - if (len(_selected) == 0): - c.warning("You must select at least 1 object") - return - c.select(hierarchy = True) - list = c.ls(selection = True, type = "transform", shapes = False) - c.select(clear = True) - for i in range(len(list)): - c.select(list[i], add = True) - @staticmethod - def BakeSelected(doNotCut=True): # TODO from GETools class (need to merge in future) - _startTime = c.playbackOptions(query = True, min = True) - _endTime = c.playbackOptions(query = True, max = True) - c.bakeResults(t = (_startTime, _endTime), preserveOutsideKeys = doNotCut, simulation = True) - - ### LOGIC - def _SetupInit(self, *args): - self._SetupDelete(False) - # Get selected objects - self.selected = c.ls(selection = True) - if (len(self.selected) == 0): - c.warning("You must select at least 1 object") - self.selected = "" - return - self.selected = self.selected[0] - # Get min/max anim range time and reset time slider - self.TimeRangeScan() - self.TimeRangeSetCurrent(self.time[2]) - # Create group - c.select(clear = True) - if (c.objExists(OVLP.nameGroup)): - c.delete(OVLP.nameGroup) - c.group(empty = True, name = OVLP.nameGroup) - # Run setup logic - self._SetupCreate(self.selected) - self._OffsetsUpdate(cacheReset = True) - c.select(self.selected, replace = True) - def _SetupCreate(self, objCurrent, *args): - # Names - _objConverted = self.ConvertText(objCurrent) - nameLocGoal = OVLP.nameLocGoalTarget[0] + _objConverted - nameLocParticle = OVLP.nameLocGoalTarget[1] + _objConverted - nameParticle = OVLP.nameParticle + _objConverted - nameLocAimBase = OVLP.nameLocAim[0] + _objConverted - nameLocAimHidden = OVLP.nameLocAim[1] + _objConverted - nameLocAim = OVLP.nameLocAim[2] + _objConverted - nameLocAimUp = OVLP.nameLocAim[3] + _objConverted - nameLoftStart = OVLP.nameLoft[0] + _objConverted - nameLoftEnd = OVLP.nameLoft[1] + _objConverted - nameLoftShape = OVLP.nameLoft[2] + _objConverted - - # Create locator for goal - self.locGoalTarget[0] = c.spaceLocator(name = nameLocGoal)[0] - c.parent(self.locGoalTarget[0], OVLP.nameGroup) - c.matchTransform(self.locGoalTarget[0], objCurrent, position = True, rotation = True) - c.parentConstraint(objCurrent, self.locGoalTarget[0], maintainOffset = True) - c.setAttr(self.locGoalTarget[0] + ".visibility", 0) - self.startPositionGoalParticle[0] = c.xform(self.locGoalTarget[0], query = True, translation = True) - - # Create particle, goal and get selected object position - _position = c.xform(objCurrent, query = True, worldSpace = True, rotatePivot = True) - self.particle = c.nParticle(name = nameParticle, position = _position, conserve = 1)[0] - c.goal(useTransformAsGoal = True, goal = self.locGoalTarget[0]) - c.parent(self.particle, OVLP.nameGroup) - # self.startPositionGoalParticle[1] = c.xform(self.particle, query = True, translation = True) - c.setAttr(self.particle + ".overrideEnabled", 1) - c.setAttr(self.particle + ".overrideDisplayType", 2) - - # Set simulation attributes - c.setAttr(self.particle + "Shape.radius", self.sliderPRadius.Get()) - c.setAttr(self.particle + "Shape.solverDisplay", 1) - c.setAttr(self.particle + "Shape.conserve", self.sliderPConserve.Get()) - c.setAttr(self.particle + "Shape.drag", self.sliderPDrag.Get()) - c.setAttr(self.particle + "Shape.damp", self.sliderPDamp.Get()) - c.setAttr(self.particle + "Shape.goalSmoothness", self.sliderGSmooth.Get()) - c.setAttr(self.particle + "Shape.goalWeight[0]", self.sliderGWeight.Get()) - - # Nucleus detection - self.nucleus = c.ls(type = "nucleus")[0] - c.parent(self.nucleus, OVLP.nameGroup) - self.sliderNTimeScale.startName = self.nucleus - c.setAttr(self.nucleus + ".gravity", 0) - c.setAttr(self.nucleus + ".timeScale", self.sliderNTimeScale.Get()) - c.setAttr(self.nucleus + ".startFrame", self.time[2]) - c.setAttr(self.nucleus + ".visibility", 0) - - # Create and connect locator to particle - self.locGoalTarget[1] = c.spaceLocator(name = nameLocParticle)[0] - c.parent(self.locGoalTarget[1], OVLP.nameGroup) - c.matchTransform(self.locGoalTarget[1], objCurrent, position = True, rotation = True) - c.connectAttr(self.particle + ".center", self.locGoalTarget[1] + ".translate", force = True) - c.setAttr(self.locGoalTarget[1] + ".visibility", 0) - - # Create base aim locator - self.locAim[0] = c.spaceLocator(name = nameLocAimBase)[0] - c.parent(self.locAim[0], OVLP.nameGroup) - c.matchTransform(self.locAim[0], objCurrent, position = True, rotation = True) - c.parentConstraint(objCurrent, self.locAim[0], maintainOffset = True) - c.setAttr(self.locAim[0] + ".visibility", 0) - - # Create hidden aim locator - self.locAim[1] = c.spaceLocator(name = nameLocAimHidden)[0] - c.matchTransform(self.locAim[1], self.locAim[0], position = True, rotation = True) - c.parent(self.locAim[1], self.locAim[0]) - c.aimConstraint(self.locGoalTarget[1], self.locAim[1], weight = 1, aimVector = (1, 0, 0), upVector = (0, 1, 0), worldUpType = "none") - c.delete(self.locAim[1] + "_aimConstraint1") - self.locAim[3] = c.duplicate(self.locAim[1], name = nameLocAimUp)[0] - c.parent(self.locAim[3], self.locAim[1]) - c.setAttr(self.locAim[3] + ".ty", 100) - c.parent(self.locAim[3], self.locAim[0]) - c.aimConstraint(self.locGoalTarget[1], self.locAim[1], weight = 1, aimVector = (1, 0, 0), upVector = (0, 1, 0), worldUpType = "object", worldUpObject = self.locAim[3]) # "scene" "object" "objectrotation" "vector" "none" - - # Create aim locator - self.locAim[2] = c.spaceLocator(name = nameLocAim)[0] - c.matchTransform(self.locAim[2], self.locAim[0], position = True, rotation = True) - c.parent(self.locAim[2], self.locAim[0]) - - # Create aim loft - self.loft[0] = c.circle(name = nameLoftStart, degree = 1, sections = 4, normal = [0, 1, 0])[0] - self.loft[1] = c.duplicate(self.loft[0], name = nameLoftEnd)[0] - _scale1 = 0.001 - _scale2 = self.sliderPRadius.Get() * OVLP.loftFactor - c.setAttr(self.loft[0] + ".scaleX", _scale1) - c.setAttr(self.loft[0] + ".scaleY", _scale1) - c.setAttr(self.loft[0] + ".scaleZ", _scale1) - c.setAttr(self.loft[1] + ".scaleX", _scale2) - c.setAttr(self.loft[1] + ".scaleY", _scale2) - c.setAttr(self.loft[1] + ".scaleZ", _scale2) - c.setAttr(self.loft[0] + ".visibility", 0) - c.setAttr(self.loft[1] + ".visibility", 0) - # - c.matchTransform(self.loft[0], self.locAim[2], position = True, rotation = True) - c.parent(self.loft[0], self.locAim[2]) - c.matchTransform(self.loft[1], self.locGoalTarget[1], position = True) - c.parent(self.loft[1], self.locGoalTarget[1]) - c.aimConstraint(self.loft[0], self.loft[1], weight = 1, aimVector = (0, 1, 0), upVector = (0, 1, 0), worldUpType = "vector", worldUpVector = (0, 0, 1)) - # - self.loft[2] = c.loft(self.loft[0], self.loft[1], name = nameLoftShape, reverseSurfaceNormals = 0, uniform = 1, polygon = 0)[0] - c.parent(self.loft[2], OVLP.nameGroup) - c.setAttr(self.loft[2] + ".overrideEnabled", 1) - c.setAttr(self.loft[2] + ".overrideDisplayType", 2) - c.setAttr(self.loft[2] + ".overrideShading", 0) - if (self._LoftGetDistance() < OVLP.loftMinDistance): - c.setAttr(self.loft[2] + ".visibility", 0) - def _SetupScan(self, *args): - # Check overlappy group - if (not c.objExists(OVLP.nameGroup)): - c.warning("Overlappy object doesn't exists") - return - # Get children of group - _children = c.listRelatives(OVLP.nameGroup) - if (len(_children) == 0): - c.warning("Overlappy object has no children objects") - return - # Try to get suffix name - _tempList = [OVLP.nameLocGoalTarget[0], OVLP.nameLocGoalTarget[1], OVLP.nameParticle, OVLP.nameLocAim[0], OVLP.nameLoft[2]] - _objectName = "" - for child in _children: - for item in _tempList: - _splitNames = child.split(item) - if (len(_splitNames) < 2): continue - _lastName = _splitNames[-1] - if (_objectName == ""): - _objectName = _lastName - else: - if (_objectName == _lastName): continue - else: c.warning("Suffix '{0}' don't equals to '{1}'".format(_objectName, _lastName)) - _converted = self.ConvertText(_objectName, False) - if (c.objExists(_converted)): - self.selected = _converted - - def CheckAndSet(name): - if (c.objExists(name + _objectName)): - return name + _objectName - else: return - # Objects - self.locGoalTarget[0] = CheckAndSet(OVLP.nameLocGoalTarget[0]) - self.locGoalTarget[1] = CheckAndSet(OVLP.nameLocGoalTarget[1]) - self.locAim[0] = CheckAndSet(OVLP.nameLocAim[0]) - self.locAim[1] = CheckAndSet(OVLP.nameLocAim[1]) - self.locAim[2] = CheckAndSet(OVLP.nameLocAim[2]) - self.particle = CheckAndSet(OVLP.nameParticle) - self.loft[0] = CheckAndSet(OVLP.nameLoft[0]) - self.loft[1] = CheckAndSet(OVLP.nameLoft[1]) - self.loft[2] = CheckAndSet(OVLP.nameLoft[2]) - # Time and offset - self.TimeRangeScan() - self.TimeRangeSetCurrent(self.time[2]) - self.startPositionGoalParticle[0] = c.xform(self.locAim[0], query = True, translation = True) - self.TimeRangeSetCurrentCached() - # Nucleus - _nucleus = c.ls(type = "nucleus") - if (len(_nucleus) > 0): - self.nucleus = _nucleus[0] - self.sliderNTimeScale.startName = self.nucleus - # Get sliders - self.sliderPRadius.Scan() - self._GetSimulation() - self._GetOffsets() - def _SetupDelete(self, deselect=True, *args): - self.selected = "" - self.locGoalTarget = ["", ""] - self.locAim = ["", "", "", ""] - self.particle = "" - self.nucleus = "" - self.loft = ["", "", ""] - # Delete group - if (c.objExists(OVLP.nameGroup)): - c.delete(OVLP.nameGroup) - # Delete nucleus node - _nucleus = c.ls(type = "nucleus") - if (len(_nucleus) > 0): - c.delete(_nucleus) - if (deselect): - c.select(clear = True) - def _OffsetsUpdate(self, cacheReset=False, *args): - if (type(cacheReset) is float): cacheReset = False - if (cacheReset): - self.sliderOffsetX.ResetCached() - self.sliderOffsetY.ResetCached() - self.sliderOffsetZ.ResetCached() - # Check and set cached value - _checkX = self.sliderOffsetX.GetCached() != self.sliderOffsetX.Get() - _checkY = self.sliderOffsetY.GetCached() != self.sliderOffsetY.Get() - _checkZ = self.sliderOffsetZ.GetCached() != self.sliderOffsetZ.Get() - if (_checkX or _checkY or _checkZ): - self.sliderOffsetX.SetCached() - self.sliderOffsetY.SetCached() - self.sliderOffsetZ.SetCached() - else: return - - self._ValuesSetOffset() - - _checkSelected = self.selected == "" or not c.objExists(self.selected) - _checkGoal = not c.objExists(self.locGoalTarget[0]) - _checkAim = not c.objExists(self.locAim[2]) - _checkStartPos = self.startPositionGoalParticle[0] == None - if (_checkSelected or _checkGoal or _checkAim or _checkStartPos): return - - c.currentTime(self.time[2]) - # Mirrors - _mirror = [1, 1, 1] - if (self.checkboxMirrorX.Get()): _mirror[0] = -1 - if (self.checkboxMirrorY.Get()): _mirror[1] = -1 - if (self.checkboxMirrorZ.Get()): _mirror[2] = -1 - # Get values from sliders - _values = [0, 0, 0] - _values[0] = self.sliderOffsetX.Get() * _mirror[0] - _values[1] = self.sliderOffsetY.Get() * _mirror[1] - _values[2] = self.sliderOffsetZ.Get() * _mirror[2] - # Set locGoal constraint offset - _goalAttributes = [0, 0, 0] - _goalAttributes[0] = self.locGoalTarget[0] + "_parentConstraint1.target[0].targetOffsetTranslateX" - _goalAttributes[1] = self.locGoalTarget[0] + "_parentConstraint1.target[0].targetOffsetTranslateY" - _goalAttributes[2] = self.locGoalTarget[0] + "_parentConstraint1.target[0].targetOffsetTranslateZ" - c.setAttr(_goalAttributes[0], _values[0]) - c.setAttr(_goalAttributes[1], _values[1]) - c.setAttr(_goalAttributes[2], _values[2]) - # Get offset - _goalPosition = c.xform(self.locGoalTarget[0], query = True, translation = True) - _goalOffset = [0, 0, 0] - _goalOffset[0] = self.startPositionGoalParticle[0][0] - _goalPosition[0] - _goalOffset[1] = self.startPositionGoalParticle[0][1] - _goalPosition[1] - _goalOffset[2] = self.startPositionGoalParticle[0][2] - _goalPosition[2] - # Set particle attributes - _particleAttributes = [0, 0, 0] - _particleAttributes[0] = OVLP.nameParticle + self.ConvertText(self.selected) + ".translateX" - _particleAttributes[1] = OVLP.nameParticle + self.ConvertText(self.selected) + ".translateY" - _particleAttributes[2] = OVLP.nameParticle + self.ConvertText(self.selected) + ".translateZ" - c.setAttr(_particleAttributes[0], self.startPositionGoalParticle[1][0] - _goalOffset[0]) - c.setAttr(_particleAttributes[1], self.startPositionGoalParticle[1][1] - _goalOffset[1]) - c.setAttr(_particleAttributes[2], self.startPositionGoalParticle[1][2] - _goalOffset[2]) - # Reposition aim up locator and reconstrain aim - _selected = c.ls(selection = True) - c.delete(self.locAim[1] + "_aimConstraint1") - c.aimConstraint(self.locGoalTarget[1], self.locAim[1], weight = 1, aimVector = (1, 0, 0), upVector = (0, 1, 0), worldUpType = "none") - c.delete(self.locAim[1] + "_aimConstraint1") - c.parent(self.locAim[3], self.locAim[1]) - c.setAttr(self.locAim[3] + ".tx", 0) - c.setAttr(self.locAim[3] + ".ty", 100) - c.setAttr(self.locAim[3] + ".tz", 0) - c.parent(self.locAim[3], self.locAim[0]) - c.aimConstraint(self.locGoalTarget[1], self.locAim[1], weight = 1, aimVector = (1, 0, 0), upVector = (0, 1, 0), worldUpType = "object", worldUpObject = self.locAim[3]) - c.select(_selected, replace = True) - # Reconstrain aim locator to hidden aim - c.setAttr(self.locAim[2] + ".rotateX", 0) - c.setAttr(self.locAim[2] + ".rotateY", 0) - c.setAttr(self.locAim[2] + ".rotateZ", 0) - c.orientConstraint(self.locAim[1], self.locAim[2], maintainOffset = True) - - ### SELECT - def _Select(self, name="", *args): - if (name != ""): - if (c.objExists(name)): - c.select(name, replace = True) - else: c.warning("'{0}' object doesn't exists".format(name)) - else: c.warning("Can't select 'None'") - def _SelectObjects(self, *args): - if (self.selected == ""): - self._Select() - else: - self._Select(self.selected) - def _SelectParticle(self, *args): - self._Select(self.particle) - def _SelectNucleus(self, *args): - self._Select(self.nucleus) - def _SelectTarget(self, *args): - self._Select(self.locGoalTarget[1]) - def _SelectAim(self, *args): - self._Select(self.locAim[2]) - - ### VALUES - def _ValuesSetSimulation(self, *args): - self.sliderPRadius.Set() - self.sliderPConserve.Set() - self.sliderPDrag.Set() - self.sliderPDamp.Set() - self.sliderGSmooth.Set() - self.sliderGWeight.Set() - self.sliderNTimeScale.Set() - self._LoftUpdate() - def _ValuesSetOffset(self, *args): - self.sliderOffsetX.Set() - self.sliderOffsetY.Set() - self.sliderOffsetZ.Set() - self._LoftUpdate() - def _LoftUpdate(self, *args): - if (self.loft[1] == ""): return - if (not c.objExists(self.loft[1])): return - _scale = self.sliderPRadius.Get() * OVLP.loftFactor - c.setAttr(self.loft[1] + ".scaleX", _scale) - c.setAttr(self.loft[1] + ".scaleY", _scale) - c.setAttr(self.loft[1] + ".scaleZ", _scale) - if (self._LoftGetDistance() < OVLP.loftMinDistance): c.setAttr(self.loft[2] + ".visibility", 0) - else: c.setAttr(self.loft[2] + ".visibility", 1) - def _LoftGetDistance(self, *args): - _vector = [0, 0, 0] - _vector[0] = self.sliderOffsetX.Get() - _vector[1] = self.sliderOffsetY.Get() - _vector[2] = self.sliderOffsetZ.Get() - return sqrt(pow(_vector[0], 2) + pow(_vector[1], 2) + pow(_vector[2], 2)) # Distance formula : V((x2 - x1)2 + (y2 - y1)2 + (z2 - z1)2) - - def _GetSimulation(self, *args): - self.sliderPConserve.Scan() - self.sliderPDrag.Scan() - self.sliderPDamp.Scan() - self.sliderGSmooth.Scan() - self.sliderGWeight.Scan() - self.sliderNTimeScale.Scan() - def _GetOffsets(self, *args): - self.sliderOffsetX.Scan() - self.sliderOffsetY.Scan() - self.sliderOffsetZ.Scan() - def _ResetAllValues(self, *args): - self.checkboxHierarchy.Reset() - self.checkboxLayer.Reset() - self.checkboxLoop.Reset() - self.checkboxClean.Reset() - self._ResetOptions() - self._ResetSimulation(True) - self._ResetOffsets() - def _ResetOptions(self, *args): - self.checkboxHierarchy.Reset() - self.checkboxLayer.Reset() - self.checkboxLoop.Reset() - self.checkboxClean.Reset() - def _ResetSimulation(self, full=False, *args): - if (full): - self.sliderPRadius.Reset() - self.sliderPConserve.Reset() - self.sliderPDrag.Reset() - self.sliderPDamp.Reset() - self.sliderGSmooth.Reset() - self.sliderGWeight.Reset() - self.sliderNTimeScale.Reset() - self._ValuesSetSimulation() - def _ResetOffsets(self, *args): - self.checkboxMirrorX.Reset() - self.checkboxMirrorY.Reset() - self.checkboxMirrorZ.Reset() - self.sliderOffsetX.Reset() - self.sliderOffsetY.Reset() - self.sliderOffsetZ.Reset() - self._ValuesSetOffset() - - ### BAKE - def _BakeLogic(self, parent, zeroOffsets=False, translation=True, deleteSetupLock=False, *args): - # Filter attributes - _item = self.selected - if (translation): _attributesType = OVLP.attributesT - else: _attributesType = OVLP.attributesR - _attrs = ["", "", ""] - for i in range(len(_attrs)): - _attrs[i] = "{0}.{1}".format(_item, _attributesType[i]) - _attributesFiltered = [] - for i in range(len(_attrs)): - _keyed = c.keyframe(_attrs[i], query = True) - if(_keyed): - _muted = c.mute(_attrs[i], query = True) - if(_muted): - continue - _locked = c.getAttr(_attrs[i], lock = True) - _keyable = c.getAttr(_attrs[i], keyable = True) - _settable = c.getAttr(_attrs[i], settable = True) - _constrained = False - _connections = c.listConnections(_attrs[i]) - if(_connections): - for item in _connections: - _type = c.nodeType(item) - if(_type in OVLP.constraintsNames): - _constrained = True - if(not _locked and _keyable and _settable and not _constrained): - _attributesFiltered.append(_attributesType[i]) - if(len(_attributesFiltered) == 0): - c.warning("No attributes") - self._SetupDelete() - return - - # Keyframe target attributes - c.setKeyframe(_item, attribute = _attributesFiltered) - - # Zero offsets - if (zeroOffsets): - _value1 = self.sliderOffsetX.Get() - _value2 = self.sliderOffsetY.Get() - _value3 = self.sliderOffsetZ.Get() - self.sliderOffsetX.Reset() - self.sliderOffsetY.Reset() - self.sliderOffsetZ.Reset() - - # Set time range - self.TimeRangeScan() - _startTime = self.time[2] - if (self.checkboxLoop.Get()): - _startTime = self.time[2] - self.time[3] * self.loopOffset - self.TimeRangeSetMin(_startTime) - self.TimeRangeSetCurrent(_startTime) - c.setAttr(self.nucleus + ".startFrame", _startTime) # TODO bug when select ovlp objects - - # Start logic - _name = "_rebake_" + self.ConvertText(_item) - _clone = c.duplicate(_item, name = _name, parentOnly = True, transformsOnly = True, smartTransform = True, returnRootsOnly = True) - for attr in OVLP.attributesT: - c.setAttr(_clone[0] + "." + attr, lock = False) - for attr in OVLP.attributesR: - c.setAttr(_clone[0] + "." + attr, lock = False) - c.parentConstraint(parent, _clone, maintainOffset = True) # skipTranslate - c.select(_clone, replace = True) - - # Bake - OVLP.BakeSelected() - _children = c.listRelatives(_clone, type = "constraint") - for child in _children: c.delete(child) - - # Copy keys, check layer and paste keys - c.copyKey(_clone, time = (self.time[2], self.time[3]), attribute = _attributesFiltered) - if (self.checkboxLayer.Get()): - _animLayer = self._LayerCreate(_item) - _attrsLayer = [] - for item in _attributesFiltered: - _attrsLayer.append("{0}.{1}".format(_item, item)) - c.animLayer(_animLayer, edit = True, attribute = _attrsLayer) - c.pasteKey(_item, option = "replace", attribute = _attributesFiltered, animLayer = _animLayer) - else: - c.pasteKey(_item, option = "replaceCompletely", attribute = _attributesFiltered) - c.delete(_clone) - - # Set time range - if (self.checkboxLoop.Get()): - _startTime = self.time[2] - c.setAttr(self.nucleus + ".startFrame", _startTime) - self.TimeRangeReset() - c.setInfinity(_item, preInfinite = "cycle", postInfinite = "cycle") - else: - c.setInfinity(_item, preInfinite = "constant", postInfinite = "constant") - - # Delete setup - if (self.checkboxClean.Get()): - if (not deleteSetupLock): - self._SetupDelete() - - # Restore offsets sliders - if (zeroOffsets): - self.sliderOffsetX.Set(_value1) - self.sliderOffsetY.Set(_value2) - self.sliderOffsetZ.Set(_value3) - self._OffsetsUpdate(True) - def _BakeCheck(self, *args): - _selected = c.ls(selection = True) # type = "transform" - if (len(_selected) == 0): - if (self.selected == ""): return None - return 0, None - else: - if (self.checkboxHierarchy.Get()): - self.SelectTransformHierarchy() - _selected = c.ls(selection = True) - return len(_selected), _selected - def _BakeVariants(self, variant, *args): - _selected = self._BakeCheck() - if (_selected == None): return - - if (_selected[0] == 0): - if (variant == 1): - self._BakeLogic(self.locGoalTarget[1], True, True, False) - elif (variant == 2): - self._BakeLogic(self.locGoalTarget[1], False, True, False) - elif (variant == 3): - self._BakeLogic(self.locAim[2], False, False, False) - elif (variant == 4): - self._BakeLogic(self.locGoalTarget[1], True, True, True) - self._BakeLogic(self.locAim[2], False, False, False) - else: - for ii in range(_selected[0]): - c.select(_selected[1][ii], replace = True) - self._SetupInit() - if (variant == 1): - self._BakeLogic(self.locGoalTarget[1], True, True, False) - elif (variant == 2): - self._BakeLogic(self.locGoalTarget[1], False, True, False) - elif (variant == 3): - self._BakeLogic(self.locAim[2], False, False, False) - elif (variant == 4): - self._BakeLogic(self.locGoalTarget[1], True, True, True) - self._BakeLogic(self.locAim[2], False, False, False) - c.select(_selected[1], replace = True) - def _BakeVariantComboTR(self, *args): - self._BakeVariants(1) - self._BakeVariants(3) - def _BakeVariantComboRT(self, *args): - self._BakeVariants(3) - self._BakeVariants(1) - def _BakeWorldLocator(self, *args): - _selected = c.ls(selection = True) # Get selected objects - if (len(_selected) == 0): - c.warning("You must select at least 1 object") - return - else: - if (self.checkboxHierarchy.Get()): - self.SelectTransformHierarchy() - _selected = c.ls(selection = True) - _locators = [] - for item in _selected: # Create locator - _name = OVLP.nameBakedWorldLocator + "1" - _locator = c.spaceLocator(name = _name)[0] - c.matchTransform(_locator, item, position = True, rotation = True) - c.parentConstraint(item, _locator, maintainOffset = True) - c.scaleConstraint(item, _locator, maintainOffset = True) - _scale = 50 - c.setAttr(_locator + "Shape.localScaleX", _scale) - c.setAttr(_locator + "Shape.localScaleY", _scale) - c.setAttr(_locator + "Shape.localScaleZ", _scale) - _locators.append(_locator) - c.select(_locators, replace = True) # Bake and cleanup - OVLP.BakeSelected() - for loc in _locators: - _children = c.listRelatives(loc, type = "constraint") - for child in _children: - c.delete(child) - - ### LAYERS - def _LayerCreate(self, obj, *args): - # Create main layer - if(not c.objExists(OVLP.nameLayers[0])): - self.layers[0] = c.animLayer(OVLP.nameLayers[0], override = True) - # Create layers on selected - _name = OVLP.nameLayers[2] + self.ConvertText(obj) + "_1" - return c.animLayer(_name, override = True, parent = self.layers[0]) - def _LayerMoveToSafeOrBase(self, safeLayer=True, *args): - _id = [0, 1] - if (not safeLayer): _id = [1, 0] - _layer1 = OVLP.nameLayers[_id[0]] - _layer2 = OVLP.nameLayers[_id[1]] - - # Check source layer - if(not c.objExists(_layer1)): - c.warning("Layer '{0}' doesn't exist".format(_layer1)) - return - # Get selected layers - _selectedLayers = [] - for animLayer in c.ls(type = "animLayer"): - if c.animLayer(animLayer, query = True, selected = True): - _selectedLayers.append(animLayer) - # Check selected count - _children = c.animLayer(self.layers[_id[0]], query = True, children = True) - _filteredLayers = [] - if (len(_selectedLayers) == 0): - if (_children == None): - c.warning("Layer '{0}' is empty".format(_layer1)) - return - else: - for layer in _children: - _filteredLayers.append(layer) - else: - if (_children == None): - c.warning("Layer '{0}' is empty".format(_layer1)) - return - else: - for layer1 in _children: - for layer2 in _selectedLayers: - if (layer1 == layer2): - _filteredLayers.append(layer1) - if (len(_filteredLayers) == 0): - c.warning("Nothing to move") - return - # Create safe layer - if(not c.objExists(_layer2)): - self.layers[_id[1]] = c.animLayer(_layer2, override = True) - # Move children or selected layers - for layer in _filteredLayers: - c.animLayer(layer, edit = True, parent = self.layers[_id[1]]) - # Delete base layer if no children - if (len(_filteredLayers) == len(_children)): - self._LayerDelete(_layer1) - def _LayerDelete(self, name, *args): - if(c.objExists(name)): - c.delete(name) - print("Layer '{0}' deleted".format(name)) - else: - c.warning("Layer '{0}' doesn't exist".format(name)) - def _LayerCreate_TEST(self, *args): - # Check selected - _selected = c.ls(selection = True) - if (len(_selected) == 0): - c.warning("You must select at least 1 object") - return - # Create main layer - if(not c.objExists(OVLP.nameLayers[0])): - self.layers[0] = c.animLayer(OVLP.nameLayers[0], override = True) - # Create layers on selected - for item in _selected: - _name = OVLP.nameLayers[2] + self.ConvertText(item) + "_1" - c.animLayer(_name, override = True, parent = self.layers[0]) - - ### DEV TOOLS - def _DEVFunction(self, *args): - print("DEV Function") - def _MotionTrailCreate(self, *args): - _selected = c.ls(selection = True) # Get selected objects - if (len(_selected) == 0): - c.warning("You must select at least 1 object") - return - _name = "MotionTrail_1" - _step = 1 - _start = c.playbackOptions(query = True, minTime = True) - _end = c.playbackOptions(query = True, maxTime = True) - c.snapshot(name = _name, motionTrail = True, increment = _step, startTime = _start, endTime = _end) - _trails = c.ls(type = "motionTrail") - for item in _trails: - c.setAttr(item + "Handle" + "Shape.trailDrawMode", 1) - c.setAttr(item + "Handle" + "Shape.template", 1) - def _MotionTrailSelect(self, *args): - _trails = c.ls(type = "motionTrail") - if (len(_trails) == 0): return - c.select(clear = True) - for item in _trails: - c.select(item + "Handle", add = True) - def _MotionTrailDelete(self, *args): - _trails = c.ls(type = "motionTrail") - if (len(_trails) == 0): return - for item in _trails: - c.delete(item + "Handle") - - ### EXECUTION - def Start(self, *args): - _OVERLAPPY.CreateUI() - def Restart(self, *args): - c.evalDeferred("_OVERLAPPY.Start()") - -_OVERLAPPY = OVLP() -_OVERLAPPY.Start() \ No newline at end of file diff --git a/GETOOLS_SOURCE/modules/CenterOfMass.py b/GETOOLS_SOURCE/modules/CenterOfMass.py index 7475e90..8d59192 100644 --- a/GETOOLS_SOURCE/modules/CenterOfMass.py +++ b/GETOOLS_SOURCE/modules/CenterOfMass.py @@ -73,7 +73,6 @@ def __init__(self): self.layoutSetup = None self.layoutWeights = None self.layoutBaking = None - def UICreate(self, layoutMain): windowWidthMargin = Settings.windowWidthMargin lineHeight = Settings.lineHeight @@ -81,25 +80,25 @@ def UICreate(self, layoutMain): self.UILayoutSetup(layoutMain, windowWidthMargin, lineHeight) self.UILayoutWeights(layoutMain, windowWidthMargin, lineHeight) self.UILayoutBaking(layoutMain, windowWidthMargin, lineHeight) - def UILayoutSetup(self, layoutMain, windowWidthMargin, lineHeight): self.layoutSetup = cmds.frameLayout(parent = layoutMain, label = "SETUP", collapsable = True) # , backgroundColor = Colors.blackWhite10 + layoutColumn = cmds.columnLayout(parent = self.layoutSetup, adjustableColumn = True) # COMButtons1 = 4 - cmds.gridLayout(parent = self.layoutSetup, numberOfColumns = COMButtons1, cellWidth = windowWidthMargin / COMButtons1, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = COMButtons1, cellWidth = windowWidthMargin / COMButtons1, cellHeight = lineHeight) cmds.button(label = "CREATE", command = self.COMCreate, backgroundColor = Colors.green50, annotation = CenterOfMassAnnotations.create) cmds.button(label = "ACTIVATE", command = self.COMActivate, backgroundColor = Colors.yellow50, annotation = CenterOfMassAnnotations.activate) cmds.button(label = "SELECT", command = self.COMSelect, backgroundColor = Colors.lightBlue50, annotation = CenterOfMassAnnotations.select) cmds.button(label = "CLEAN", command = self.COMClean, backgroundColor = Colors.red50, annotation = CenterOfMassAnnotations.clean) # COMButtons2 = 3 - cmds.gridLayout(parent = self.layoutSetup, numberOfColumns = COMButtons2, cellWidth = windowWidthMargin / COMButtons2, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = COMButtons2, cellWidth = windowWidthMargin / COMButtons2, cellHeight = lineHeight) cmds.button(label = "PROJECTOR YZ", command = partial(self.COMFloorProjection, "x"), backgroundColor = Colors.red10, annotation = CenterOfMassAnnotations.projectorYZ) cmds.button(label = "PROJECTOR XZ", command = partial(self.COMFloorProjection, "y"), backgroundColor = Colors.green10, annotation = CenterOfMassAnnotations.projectorXZ) cmds.button(label = "PROJECTOR XY", command = partial(self.COMFloorProjection, "z"), backgroundColor = Colors.blue10, annotation = CenterOfMassAnnotations.projectorXY) - def UILayoutWeights(self, layoutMain, windowWidthMargin, lineHeight): self.layoutWeights = cmds.frameLayout(parent = layoutMain, label = "WEIGHTS", collapsable = True) + layoutColumn = cmds.columnLayout(parent = self.layoutWeights, adjustableColumn = True) def PartButton(partInfo = ("", 0), minMaxValue = CenterOfMassSettings.weightMinMax, onlyValue = False, annotation = ""): value = partInfo[1] @@ -110,7 +109,7 @@ def PartButton(partInfo = ("", 0), minMaxValue = CenterOfMassSettings.weightMinM # WEIGHTS PALETTE count = 14 - cmds.gridLayout(parent = self.layoutWeights, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) def CustomButton(value): PartButton(("", value), onlyValue = True, annotation = CenterOfMassAnnotations.weightsCustom) CustomButton(0) @@ -130,7 +129,7 @@ def CustomButton(value): PartButton(("", value), onlyValue = True, annotation = # BODYPARTS count = 3 - layoutBodyGrid = cmds.gridLayout(parent = self.layoutWeights, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = 70) # 23.5 per 1 button + layoutBodyGrid = cmds.gridLayout(parent = layoutColumn, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = 70) # 23.5 per 1 button cmds.columnLayout(parent = layoutBodyGrid, adjustableColumn = True) PartButton(CenterOfMassSettings.partHead, minMaxValue = (CenterOfMassSettings.partHand[1], CenterOfMassSettings.partChest[1]), annotation = CenterOfMassAnnotations.weightHead) @@ -146,7 +145,6 @@ def CustomButton(value): PartButton(("", value), onlyValue = True, annotation = PartButton(CenterOfMassSettings.partThigh, minMaxValue = (CenterOfMassSettings.partHand[1], CenterOfMassSettings.partChest[1]), annotation = CenterOfMassAnnotations.weightThigh) PartButton(CenterOfMassSettings.partKnee, minMaxValue = (CenterOfMassSettings.partHand[1], CenterOfMassSettings.partChest[1]), annotation = CenterOfMassAnnotations.weightKnee) PartButton(CenterOfMassSettings.partFoot, minMaxValue = (CenterOfMassSettings.partHand[1], CenterOfMassSettings.partChest[1]), annotation = CenterOfMassAnnotations.weightFoot) - def UILayoutBaking(self, layoutMain, windowWidthMargin, lineHeight): self.layoutBaking = cmds.frameLayout(parent = layoutMain, label = "BAKING", collapsable = True) diff --git a/GETOOLS_SOURCE/modules/GeneralWindow.py b/GETOOLS_SOURCE/modules/GeneralWindow.py index 08761b5..bf40564 100644 --- a/GETOOLS_SOURCE/modules/GeneralWindow.py +++ b/GETOOLS_SOURCE/modules/GeneralWindow.py @@ -6,8 +6,8 @@ from GETOOLS_SOURCE.utils import Colors from GETOOLS_SOURCE.utils import Install from GETOOLS_SOURCE.utils import Layers -from GETOOLS_SOURCE.utils import MotionTrail from GETOOLS_SOURCE.utils import MayaSettings +from GETOOLS_SOURCE.utils import MotionTrail from GETOOLS_SOURCE.utils import Scene from GETOOLS_SOURCE.utils import Selector @@ -18,7 +18,7 @@ from GETOOLS_SOURCE.modules import Tools as tls class GeneralWindow: - version = "v0.0.10" + version = "v0.0.11" name = "GETools" title = name + " " + version @@ -54,7 +54,7 @@ def LayoutMenuBar(self, parentLayout): cmds.menuItem(label = "Reload Scene (force)", command = Scene.Reload) cmds.menuItem(label = "Exit Maya (force)", command = Scene.ExitMaya) cmds.menuItem(divider = True) - cmds.menuItem(label = "Restart GETools", command = self.RUN_DOCKED) + cmds.menuItem(label = "Restart GETools", command = partial(self.RUN_DOCKED, "", True)) cmds.menuItem(label = "Close GETools", command = self.DockDelete) # cmds.menu(label = "Edit", tearOff = True) @@ -70,8 +70,14 @@ def LayoutMenuBar(self, parentLayout): cmds.menuItem(label = "Dock Right", command = partial(self.DockToSide, Settings.dockAllowedAreas[1])) cmds.menuItem(label = "Undock", command = self.DockOff) + def ColorsPalette(*args): + colorCalibration = Colors.ColorsPalette() + colorCalibration.CreateUI() cmds.menu(label = "Utils", tearOff = True) + cmds.menuItem(label = "Select Transform Hiererchy", command = Selector.SelectTransformHierarchy) cmds.menuItem(label = "Print selected objects to console", command = Selector.PrintSelected) + cmds.menuItem(divider = True) + cmds.menuItem(label = "Open Colors Palette", command = ColorsPalette) cmds.menu(label = "Help", tearOff = True) # , helpMenu = True def LinkVersionHistory(self): cmds.showHelp("https://github.com/GenEugene/GETools/blob/master/changelog.txt", absolute = True) @@ -127,7 +133,6 @@ def LayerMove(*args): cmds.menuItem(label = "Layer Move", command = LayerMove) cmds.menuItem(dividerLabel = "Install to shelf", divider = True) cmds.menuItem(label = "Install Select Hierarchy", command = partial(Install.ToShelf_SelectHierarchy, self.directory)) - def LayoutTools(self, parentLayout): self.frameTools = cmds.frameLayout("layoutTools", parent = parentLayout, label = tls.Tools.title, collapsable = True, backgroundColor = Colors.blackWhite10, marginWidth = Settings.margin, marginHeight = Settings.margin) tls.Tools().UICreate(self.frameTools) @@ -195,9 +200,10 @@ def DockCheck(self, *args): def DockDelete(self, *args): if self.DockCheck(): cmds.deleteUI(Settings.dockName, control = True) - print("Dock Control deleted") - else: - print("No Dock") + # print("Dock Control deleted") + # else: + # print("No Dock") + pass def DockOff(self, *args): if self.DockCheck(): cmds.dockControl(Settings.dockName, edit = True, floating = True, height = Settings.windowHeight) @@ -209,15 +215,20 @@ def DockToSide(self, areaSide, *args): cmds.dockControl(Settings.dockName, edit = True, floating = False, area = areaSide) else: cmds.dockControl(Settings.dockName, label = GeneralWindow.title, content = Settings.windowName, area = areaSide, allowedArea = Settings.dockAllowedAreas) # , backgroundColor = Colors.lightBlue10 - print("{0} docked {1}".format(GeneralWindow.title, areaSide)) + print("{0} docked to {1}".format(GeneralWindow.title, areaSide)) # EXECUTION def WindowCreate(self, *args): self.CreateUI() self.FramesCollapse(True) - def RUN_DOCKED(self, path = "", *args): + def RUN_DOCKED(self, path = "", forced = False, *args): self.directory = path + if (forced == False and self.DockCheck()): # for script toggling. Comment these 3 lines if you need to deactivate toggling + self.DockDelete() + print("{0} closed".format(GeneralWindow.title)) + return + self.DockDelete() self.WindowCreate() self.DockToSide(Settings.dockStartArea) diff --git a/GETOOLS_SOURCE/modules/Overlappy.py b/GETOOLS_SOURCE/modules/Overlappy.py index 0598cd9..23f8da2 100644 --- a/GETOOLS_SOURCE/modules/Overlappy.py +++ b/GETOOLS_SOURCE/modules/Overlappy.py @@ -4,11 +4,11 @@ from math import pow, sqrt from functools import partial +from GETOOLS_SOURCE.utils import Animation from GETOOLS_SOURCE.utils import Baker from GETOOLS_SOURCE.utils import Colors from GETOOLS_SOURCE.utils import Layers from GETOOLS_SOURCE.utils import MayaSettings -from GETOOLS_SOURCE.utils import Other from GETOOLS_SOURCE.utils import Selector from GETOOLS_SOURCE.utils import Text from GETOOLS_SOURCE.utils import Timeline @@ -179,9 +179,10 @@ def UILayoutMenuBar(self, layoutMain, windowWidthMargin): def UILayoutButtons(self, layoutMain, windowWidthMargin, lineHeight): # SETUP self.layoutButtons = cmds.frameLayout("layoutButtons", label = "BUTTONS", parent = layoutMain, collapsable = True) + layoutColumn = cmds.columnLayout(parent = self.layoutButtons, adjustableColumn = True) count = 2 - cmds.gridLayout(parent = self.layoutButtons, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) # cmds.button(label = "SETUP", command = self._SetupInit, backgroundColor = Colors.green10, annotation = OverlappyAnnotations.setup) # cmds.button(label = "Scan setup into scene", command = self._SetupScan, backgroundColor = Colors.green10) @@ -189,7 +190,7 @@ def UILayoutButtons(self, layoutMain, windowWidthMargin, lineHeight): # BAKING count = 3 - cmds.gridLayout(parent = self.layoutButtons, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) # cmds.button(label = "TRANSLATION", command = partial(self._BakeVariants, 1), backgroundColor = Colors.orange10, annotation = OverlappyAnnotations.translation) cmds.popupMenu() @@ -205,13 +206,14 @@ def UILayoutButtons(self, layoutMain, windowWidthMargin, lineHeight): pass def UILayoutLayers(self, layoutMain, windowWidthMargin, lineHeight): self.layoutLayers = cmds.frameLayout("layoutLayers", label = "LAYERS", parent = layoutMain, collapsable = True) + layoutColumn = cmds.columnLayout(parent = self.layoutLayers, adjustableColumn = True) count = 1 - cmds.gridLayout(parent = self.layoutLayers, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) cmds.button(label = "Delete BaseAnimation layer", command = partial(Layers.Delete, "BaseAnimation"), backgroundColor = Colors.red50, annotation = OverlappyAnnotations.layerDeleteBase) count = 2 - cmds.gridLayout(parent = self.layoutLayers, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) cmds.button(label = "Delete Temp layer", command = partial(Layers.Delete, OverlappySettings.nameLayers[0]), backgroundColor = Colors.red10, annotation = OverlappyAnnotations.layerDeleteTemp) cmds.button(label = "Move to Safe layer", command = partial(self._LayerMoveToSafeOrTemp, True), backgroundColor = Colors.blue10, annotation = OverlappyAnnotations.layerMoveTemp) @@ -225,18 +227,19 @@ def UILayoutOptions(self, layoutMain, windowWidthMargin, lineHeight): # _optionsResetAll = self._ResetOptions # , commandResetAll = _optionsResetAll - self.checkboxHierarchy = UI.Checkbox(label = "Hierarchy", value = OverlappySettings.checkboxesOptions[0], menuReset = True, annotation = OverlappyAnnotations.checkboxHierarchy) - self.checkboxLayer = UI.Checkbox(label = "Layer", value = OverlappySettings.checkboxesOptions[1], menuReset = True, annotation = OverlappyAnnotations.checkboxLayer) - self.checkboxLoop = UI.Checkbox(label = "Loop", value = OverlappySettings.checkboxesOptions[2], menuReset = True, annotation = OverlappyAnnotations.checkboxLoop) # FIXME make cycle infinity before bake - self.checkboxClean = UI.Checkbox(label = "Clean", value = OverlappySettings.checkboxesOptions[3], menuReset = True, annotation = OverlappyAnnotations.checkboxClean) + self.checkboxHierarchy = UI.Checkbox(label = "Hierarchy", value = OverlappySettings.checkboxesOptions[0], annotation = OverlappyAnnotations.checkboxHierarchy) + self.checkboxLayer = UI.Checkbox(label = "Layer", value = OverlappySettings.checkboxesOptions[1], annotation = OverlappyAnnotations.checkboxLayer) + self.checkboxLoop = UI.Checkbox(label = "Loop", value = OverlappySettings.checkboxesOptions[2], annotation = OverlappyAnnotations.checkboxLoop) # FIXME make cycle infinity before bake + self.checkboxClean = UI.Checkbox(label = "Clean", value = OverlappySettings.checkboxesOptions[3], annotation = OverlappyAnnotations.checkboxClean) def UILayoutParticleAttributes(self, layoutMain, windowWidthMargin, lineHeight, sliderWidth, sliderWidthMarker): self.layoutSimulation = cmds.frameLayout("layoutParticleSliders", label = "PARTICLE ATTRIBUTES", parent = layoutMain, collapsable = True) + layoutColumn = cmds.columnLayout(parent = self.layoutSimulation, adjustableColumn = True) # cmds.popupMenu() # cmds.menuItem(label = "Right-Click") # TODO add reset all function commandDefault = self._UpdateParticleAttributes - layoutSliders1 = cmds.gridLayout(parent = self.layoutSimulation, numberOfColumns = 1, cellWidth = windowWidthMargin, cellHeight = lineHeight) + layoutSliders1 = cmds.gridLayout(parent = layoutColumn, numberOfColumns = 1, cellWidth = windowWidthMargin, cellHeight = lineHeight) self.sliderPRadius = UI.Slider( parent = layoutSliders1, widthWindow = windowWidthMargin, @@ -251,9 +254,9 @@ def UILayoutParticleAttributes(self, layoutMain, windowWidthMargin, lineHeight, ) # cmds.separator(parent = self.layoutSimulation, style = "in", height = 1) - cmds.separator(parent = self.layoutSimulation, style = "in") + cmds.separator(parent = layoutColumn, style = "in") - layoutSliders2 = cmds.gridLayout(parent = self.layoutSimulation, numberOfColumns = 1, cellWidth = windowWidthMargin, cellHeight = lineHeight) + layoutSliders2 = cmds.gridLayout(parent = layoutColumn, numberOfColumns = 1, cellWidth = windowWidthMargin, cellHeight = lineHeight) self.sliderPConserve = UI.Slider( parent = layoutSliders2, widthWindow = windowWidthMargin, @@ -333,11 +336,12 @@ def UILayoutParticleAttributes(self, layoutMain, windowWidthMargin, lineHeight, ) def UILayoutParticleOffset(self, layoutMain, windowWidthMargin, lineHeight, sliderWidth, sliderWidthMarker): self.layoutOffset = cmds.frameLayout("layoutParticleOffset", label = "PARTICLE OFFSET - use for baking rotation", parent = layoutMain, collapsable = True) + layoutColumn = cmds.columnLayout(parent = self.layoutOffset, adjustableColumn = True) # cmds.popupMenu() # cmds.menuItem(label = "Right-Click") # TODO add reset all function count = 3 - cmds.gridLayout(parent = self.layoutOffset, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = count, cellWidth = windowWidthMargin / count, cellHeight = lineHeight) # cmds.separator() # , commandResetAll = self._ResetOffsets self.checkboxMirrorX = UI.Checkbox(label = "Mirror X", command = partial(self._OffsetsUpdate, True), annotation = OverlappyAnnotations.offsetMirrorX) @@ -345,7 +349,7 @@ def UILayoutParticleOffset(self, layoutMain, windowWidthMargin, lineHeight, slid self.checkboxMirrorZ = UI.Checkbox(label = "Mirror Z", command = partial(self._OffsetsUpdate, True), annotation = OverlappyAnnotations.offsetMirrorZ) - layoutSliders = cmds.gridLayout(parent = self.layoutOffset, numberOfColumns = 1, cellWidth = windowWidthMargin, cellHeight = lineHeight) + layoutSliders = cmds.gridLayout(parent = layoutColumn, numberOfColumns = 1, cellWidth = windowWidthMargin, cellHeight = lineHeight) commandDefault = self._OffsetsUpdate @@ -909,9 +913,9 @@ def _BakeLogic(self, parent, zeroOffsets = False, translation = True, deleteSetu _startTime = self.time.values[2] cmds.setAttr(self.nucleus + ".startFrame", _startTime) self.time.Reset() - Other.SetInfinityCycle(_item) + Animation.SetInfinityCycle(_item) else: - Other.SetInfinityConstant(_item) + Animation.SetInfinityConstant(_item) # Delete setup if (self.checkboxClean.Get()): diff --git a/GETOOLS_SOURCE/modules/Rigging.py b/GETOOLS_SOURCE/modules/Rigging.py index c88c701..f672593 100644 --- a/GETOOLS_SOURCE/modules/Rigging.py +++ b/GETOOLS_SOURCE/modules/Rigging.py @@ -6,6 +6,7 @@ from GETOOLS_SOURCE.utils import Colors from GETOOLS_SOURCE.utils import Constraints from GETOOLS_SOURCE.utils import Other +from GETOOLS_SOURCE.utils import Selector from GETOOLS_SOURCE.utils import Skinning from GETOOLS_SOURCE.utils import UI @@ -16,11 +17,13 @@ class RiggingAnnotations: _textAllSelectedConstrainToLast = "All selected objects will be constrained to last selected object" constraintReverse = "Reverse the direction of operation from last to first selected" constraintMaintain = "Use maintain offset" + constraintOffset = "[IN DEVELOPMENT]\nAdd extra locators structure with ability to make offset animation" constraintParent = "Parent constrain.\n{allToLast}".format(allToLast = _textAllSelectedConstrainToLast) constraintPoint = "Point constrain.\n{allToLast}".format(allToLast = _textAllSelectedConstrainToLast) constraintOrient = "Orient constrain.\n{allToLast}".format(allToLast = _textAllSelectedConstrainToLast) constraintScale = "Scale constrain.\n{allToLast}".format(allToLast = _textAllSelectedConstrainToLast) constraintAim = "[IN DEVELOPMENT]\nAim constrain.".format(allToLast = _textAllSelectedConstrainToLast) # TODO + constraintDelete = "Delete all constraints on selected objects" # Utils _rotateOrder = "rotate order attribute in channel box for all selected objects" @@ -35,42 +38,49 @@ class RiggingAnnotations: copySkinWeights = "Copy skin weights from last selected object to all other selected objects" class Rigging: - version = "v0.0.1" + version = "v0.0.2" name = "RIGGING" title = name + " " + version def __init__(self): self.checkboxConstraintReverse = None self.checkboxConstraintMaintain = None - + self.checkboxConstraintOffset = None def UICreate(self, layoutMain): windowWidthMargin = Settings.windowWidthMargin lineHeight = Settings.lineHeight # CONSTRAINTS layoutConstraints = cmds.frameLayout(parent = layoutMain, label = "CONSTRAINTS", collapsable = True) + layoutColumnConstraints = cmds.columnLayout(parent = layoutConstraints, adjustableColumn = True) # countOffsets = 4 - cmds.gridLayout(parent = layoutConstraints, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumnConstraints, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) cmds.separator(style = "none") - self.checkboxConstraintReverse = UI.Checkbox(label = "Reverse", value = False, menuReset = False, enabled = True, annotation = RiggingAnnotations.constraintReverse) - self.checkboxConstraintMaintain = UI.Checkbox(label = "Maintain", value = False, menuReset = False, enabled = True, annotation = RiggingAnnotations.constraintMaintain) + self.checkboxConstraintReverse = UI.Checkbox(label = "Reverse", value = False, annotation = RiggingAnnotations.constraintReverse) + self.checkboxConstraintMaintain = UI.Checkbox(label = "Maintain", value = False, annotation = RiggingAnnotations.constraintMaintain) + # self.checkboxConstraintOffset = UI.Checkbox(label = "Offset", value = False, annotation = RiggingAnnotations.constraintOffset) cmds.separator(style = "none") # countOffsets = 5 - cmds.gridLayout(parent = layoutConstraints, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumnConstraints, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) cmds.button(label = "Parent", command = self.ConstrainParent, backgroundColor = Colors.red10, annotation = RiggingAnnotations.constraintParent) cmds.button(label = "Point", command = self.ConstrainPoint, backgroundColor = Colors.red10, annotation = RiggingAnnotations.constraintPoint) cmds.button(label = "Orient", command = self.ConstrainOrient, backgroundColor = Colors.red10, annotation = RiggingAnnotations.constraintOrient) cmds.button(label = "Scale", command = self.ConstrainScale, backgroundColor = Colors.red10, annotation = RiggingAnnotations.constraintScale) - cmds.button(label = "Aim", command = self.ConstrainParent, backgroundColor = Colors.red10, annotation = RiggingAnnotations.constraintAim, enable = False) # TODO + cmds.button(label = "Aim", command = self.ConstrainAim, backgroundColor = Colors.red10, annotation = RiggingAnnotations.constraintAim, enable = False) + # + countOffsets = 1 + cmds.gridLayout(parent = layoutColumnConstraints, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.button(label = "Delete Constraints", command = self.DeleteConstraints, backgroundColor = Colors.red50, annotation = RiggingAnnotations.constraintDelete) # UTILS layoutUtils = cmds.frameLayout(parent = layoutMain, label = "UTILS", collapsable = True) + layoutColumnUtils = cmds.columnLayout(parent = layoutUtils, adjustableColumn = True) # countOffsets = 2 - cmds.gridLayout(parent = layoutUtils, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumnUtils, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) cmds.button(label = "Rotate order\nSHOW", command = partial(Other.RotateOrderVisibility, True), backgroundColor = Colors.green10, annotation = RiggingAnnotations.rotateOrderShow) cmds.button(label = "Rotate order\nHIDE", command = partial(Other.RotateOrderVisibility, False), backgroundColor = Colors.green10, annotation = RiggingAnnotations.rotateOrderHide) cmds.button(label = "Segment Scale\nCompensate ON", command = partial(Other.SegmentScaleCompensate, True), backgroundColor = Colors.yellow10, annotation = RiggingAnnotations.scaleCompensateOn) @@ -79,17 +89,25 @@ def UICreate(self, layoutMain): cmds.button(label = "Joint\nHIDDEN", command = partial(Other.JointDrawStyle, 2), backgroundColor = Colors.orange10, annotation = RiggingAnnotations.jointDrawStyleHidden) # countOffsets = 1 - cmds.gridLayout(parent = layoutUtils, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumnUtils, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) cmds.button(label = "Copy Skin Weights\nFrom Last Selected", command = Skinning.CopySkinWeightsFromLastMesh, backgroundColor = Colors.blue10, annotation = RiggingAnnotations.copySkinWeights) # CONSTRAINTS def ConstrainParent(self, *args): - Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = True, point = False, orient = False, scale = False) + Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = True, point = False, orient = False, scale = False, aim = False) def ConstrainPoint(self, *args): - Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = False, point = True, orient = False, scale = False) + Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = False, point = True, orient = False, scale = False, aim = False) def ConstrainOrient(self, *args): - Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = False, point = False, orient = True, scale = False) + Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = False, point = False, orient = True, scale = False, aim = False) def ConstrainScale(self, *args): - Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = False, point = False, orient = False, scale = True) + Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = False, point = False, orient = False, scale = True, aim = False) + def ConstrainAim(self, *args): # TODO + Constraints.ConstrainSelectedToLastObject(reverse = self.checkboxConstraintReverse.Get(), maintainOffset = self.checkboxConstraintMaintain.Get(), parent = False, point = False, orient = False, scale = False, aim = True) + + def DeleteConstraints(self, *args): + selectedList = Selector.MultipleObjects(1) + if (selectedList == None): + return + Constraints.DeleteConstraints(selectedList) diff --git a/GETOOLS_SOURCE/modules/Settings.py b/GETOOLS_SOURCE/modules/Settings.py index 511e56d..8fa04f0 100644 --- a/GETOOLS_SOURCE/modules/Settings.py +++ b/GETOOLS_SOURCE/modules/Settings.py @@ -7,9 +7,9 @@ windowHeight = 500 # used for vertical window size when undocked windowWidth = 320 -windowWidthScrollSpace = 16 +windowWidthScrollSpace = 20 lineHeight = 30 -margin = 4 +margin = 2 sliderWidth = (60, 60, 10) sliderWidthMarker = 14 diff --git a/GETOOLS_SOURCE/modules/Tools.py b/GETOOLS_SOURCE/modules/Tools.py index 741497b..2983310 100644 --- a/GETOOLS_SOURCE/modules/Tools.py +++ b/GETOOLS_SOURCE/modules/Tools.py @@ -3,11 +3,10 @@ import maya.cmds as cmds from functools import partial +from GETOOLS_SOURCE.utils import Animation from GETOOLS_SOURCE.utils import Baker from GETOOLS_SOURCE.utils import Colors from GETOOLS_SOURCE.utils import Locators -from GETOOLS_SOURCE.utils import Other -from GETOOLS_SOURCE.utils import Selector from GETOOLS_SOURCE.utils import Timeline from GETOOLS_SOURCE.utils import UI @@ -16,11 +15,11 @@ class ToolsAnnotations: # Other # printSelectedToConsole = "Just print all selected objects to console and count them" - selectTransformHiererchy = "Select all children \"transform\" objects. \nWorks with multiple selected objects" + # selectTransformHiererchy = "Select all children \"transform\" objects. \nWorks with multiple selected objects" # Locators - hideParent = "Deactivate vsibility on parent locator. \nUsually better o use with \"subLocator\" checkbox activated" - subLocator = "Create an additional locator inside the main locator for additional local control" + hideParent = "Deactivate visibility on parent locator. \nUsually better to use with \"Sub Locator\" checkbox activated" + subLocator = "Create an extra locator inside the main locator for additional local control" locatorSize = "Initial size of locator" locator = "Create new locator on the world origin" locatorMatch = "Create and match locators to selected objects" @@ -30,6 +29,8 @@ class ToolsAnnotations: locatorsBakeReverse = "{bake}\n{reverse}".format(bake = locatorsBake, reverse = _reverseConstraint) locatorsRelative = "{bake}\nThe last locator becomes the parent of other locators".format(bake = locatorsBake) locatorsRelativeReverse = "{relative}\n{reverse}\nRight click allows you to bake the same operation but with constrained last object.".format(relative = locatorsRelative, reverse = _reverseConstraint) + locatorsBakeAim = "Bake locators for Aim Space Switching" + locatorAimDistance = "Locator Aim distance from original object. Need to use non-zero value" # Bake _bakeCutOutside = "Keys outside of time range or selected range will be removed" @@ -40,9 +41,12 @@ class ToolsAnnotations: bakeByLast = "Bake selected objects relative to the last selected object as if they were constrained" # Animation - deleteNonkeyableKeys = "Delete animation on all nonkeyable attributes of selected objects" deleteAnimation = "Delete all animation from selected objects" deleteKeyRange = "Delete selected time range keys of selected objects. \nAlso works with selected attributes in Channel Box" + deleteNonkeyableKeys = "Delete animation on all nonkeyable attributes of selected objects" + deleteStaticCurves = "Delete all static curves on selected" + filterCurve = "Filter curve by euler filter. Fix some curve issues" + animationCurveInfinity = "Curve Infinity" timelineSetMinOuter = "Set minimal outer timeline value" timelineSetMinInner = "Set minimal inner timeline value" @@ -52,36 +56,37 @@ class ToolsAnnotations: timelineExpandInner = "Expand timeline range to inner range" timelineFocusRange = "Set timeline inner range on selected range by mouse" +class ToolsSettings: + # SLIDERS (field min/max, slider min/max) + rangeLocatorAimOffset = (0, float("inf"), 0, 200) + class Tools: - version = "v0.1.3" + version = "v0.1.4" name = "TOOLS" title = name + " " + version - + def __init__(self): self.checkboxLocatorHideParent = None self.checkboxLocatorSubLocator = None self.floatLocatorSize = None - + self.floatLocatorAimOffset = None def UICreate(self, layoutMain): windowWidthMargin = Settings.windowWidthMargin lineHeight = Settings.lineHeight - - - # SELECT - layoutLocators = cmds.frameLayout(parent = layoutMain, label = "SELECT", collapsable = True) - # - countOffsets = 1 - cmds.gridLayout(parent = layoutLocators, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) - cmds.button(label = "Select Transform\nHiererchy", command = Selector.SelectTransformHierarchy, backgroundColor = Colors.blue10, annotation = ToolsAnnotations.selectTransformHiererchy) - # cmds.separator(style = "none") - - # LOCATORS - layoutLocators = cmds.frameLayout(parent = layoutMain, label = "LOCATORS", collapsable = True) + sliderWidth = Settings.sliderWidth + sliderWidthMarker = Settings.sliderWidthMarker + + self.UILayoutLocators(layoutMain, windowWidthMargin, lineHeight, sliderWidth, sliderWidthMarker) + self.UILayoutBaking(layoutMain, windowWidthMargin, lineHeight) + self.UILayoutAnimation(layoutMain, windowWidthMargin, lineHeight) + def UILayoutLocators(self, layoutMain, windowWidthMargin, lineHeight, sliderWidth, sliderWidthMarker): + layoutLocators = cmds.frameLayout(parent = layoutMain, label = "LOCATORS / SPACE SWITCHING", collapsable = True) + layoutColumn = cmds.columnLayout(parent = layoutLocators, adjustableColumn = True) # countOffsets = 3 - cmds.gridLayout(parent = layoutLocators, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) - self.checkboxLocatorHideParent = UI.Checkbox(label = "Hide Parent", value = False, menuReset = False, annotation = ToolsAnnotations.hideParent) - self.checkboxLocatorSubLocator = UI.Checkbox(label = "Sub Locator", value = False, menuReset = False, annotation = ToolsAnnotations.subLocator) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + self.checkboxLocatorHideParent = UI.Checkbox(label = "Hide Parent", value = False, annotation = ToolsAnnotations.hideParent) + self.checkboxLocatorSubLocator = UI.Checkbox(label = "Sub Locator", value = False, annotation = ToolsAnnotations.subLocator) self.floatLocatorSize = UI.FloatField(value = 5, precision = 3, annotation = ToolsAnnotations.locatorSize) # cmds.button(label = "Locator", command = self.CreateLocator, backgroundColor = Colors.green10, annotation = ToolsAnnotations.locator) @@ -89,67 +94,135 @@ def UICreate(self, layoutMain): cmds.button(label = "Locators parent", command = self.CreateLocatorParent, backgroundColor = Colors.green10, annotation = ToolsAnnotations.locatorParent) # countOffsets = 2 - cmds.gridLayout(parent = layoutLocators, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) cmds.button(label = "Locators bake", command = self.CreateLocatorBake, backgroundColor = Colors.yellow10, annotation = ToolsAnnotations.locatorsBake) cmds.button(label = "Locators bake + reverse", command = self.CreateLocatorBakeReverse, backgroundColor = Colors.yellow50, annotation = ToolsAnnotations.locatorsBakeReverse) cmds.button(label = "Locators relative", command = self.BakeAsChildrenFromLastSelected, backgroundColor = Colors.orange10, annotation = ToolsAnnotations.locatorsRelative) cmds.button(label = "Locators relative + reverse", command = self.BakeAsChildrenFromLastSelectedReverse, backgroundColor = Colors.orange50, annotation = ToolsAnnotations.locatorsRelativeReverse) cmds.popupMenu() cmds.menuItem(label = "skip last object constrain", command = self.BakeAsChildrenFromLastSelectedReverseSkipLast) - - - # BAKE - layoutBake = cmds.frameLayout(parent = layoutMain, label = "BAKE", collapsable = True) + # + layoutAim = cmds.gridLayout(parent = layoutColumn, numberOfColumns = 1, cellWidth = windowWidthMargin, cellHeight = lineHeight) + countOffsets = 6 + labelLocalSpace = "without reverse constraint" + cmds.gridLayout(parent = layoutAim, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.button(label = "-X", command = partial(self.CreateLocatorBakeAim, 1, True), backgroundColor = Colors.red10, annotation = ToolsAnnotations.locatorsBakeAim) # TODO + cmds.popupMenu() + cmds.menuItem(label = labelLocalSpace, command = partial(self.CreateLocatorBakeAim, 1, False)) + cmds.button(label = "+X", command = partial(self.CreateLocatorBakeAim, 2, True), backgroundColor = Colors.red50, annotation = ToolsAnnotations.locatorsBakeAim) # TODO + cmds.popupMenu() + cmds.menuItem(label = labelLocalSpace, command = partial(self.CreateLocatorBakeAim, 2, False)) + cmds.button(label = "-Y", command = partial(self.CreateLocatorBakeAim, 3, True), backgroundColor = Colors.green10, annotation = ToolsAnnotations.locatorsBakeAim) # TODO + cmds.popupMenu() + cmds.menuItem(label = labelLocalSpace, command = partial(self.CreateLocatorBakeAim, 3, False)) + cmds.button(label = "+Y", command = partial(self.CreateLocatorBakeAim, 4, True), backgroundColor = Colors.green50, annotation = ToolsAnnotations.locatorsBakeAim) # TODO + cmds.popupMenu() + cmds.menuItem(label = labelLocalSpace, command = partial(self.CreateLocatorBakeAim, 4, False)) + cmds.button(label = "-Z", command = partial(self.CreateLocatorBakeAim, 5, True), backgroundColor = Colors.blue10, annotation = ToolsAnnotations.locatorsBakeAim) # TODO + cmds.popupMenu() + cmds.menuItem(label = labelLocalSpace, command = partial(self.CreateLocatorBakeAim, 5, False)) + cmds.button(label = "+Z", command = partial(self.CreateLocatorBakeAim, 6, True), backgroundColor = Colors.blue50, annotation = ToolsAnnotations.locatorsBakeAim) # TODO + cmds.popupMenu() + cmds.menuItem(label = labelLocalSpace, command = partial(self.CreateLocatorBakeAim, 6, False)) + self.floatLocatorAimOffset = UI.Slider( + parent = layoutAim, + widthWindow = windowWidthMargin, + widthMarker = sliderWidthMarker, + columnWidth3 = sliderWidth, + # command = , + label = "Distance", + annotation = ToolsAnnotations.locatorAimDistance, + value = 100, + minMax = ToolsSettings.rangeLocatorAimOffset, + precision = 3, + menuReset = True, + ) + def UILayoutBaking(self, layoutMain, windowWidthMargin, lineHeight): + layoutBake = cmds.frameLayout(parent = layoutMain, label = "BAKING", collapsable = True) + layoutColumn = cmds.columnLayout(parent = layoutBake, adjustableColumn = True) # countOffsets = 2 - cmds.gridLayout(parent = layoutBake, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + # TODO classic bake to new override layer cmds.button(label = "Bake Classic", command = self.BakeSelectedClassic, backgroundColor = Colors.orange10, annotation = ToolsAnnotations.bakeClassic) cmds.button(label = "Bake Classic\nCut Outer", command = self.BakeSelectedClassicCut, backgroundColor = Colors.orange10, annotation = ToolsAnnotations.bakeClassicCut) cmds.button(label = "Bake Custom", command = self.BakeSelectedCustom, backgroundColor = Colors.orange50, annotation = ToolsAnnotations.bakeCustom) cmds.button(label = "Bake Custom\nCut Outer", command = self.BakeSelectedCustomCut, backgroundColor = Colors.orange50, annotation = ToolsAnnotations.bakeCustomCut) + # + countOffsets = 1 + cmds.gridLayout(parent = layoutColumn, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) cmds.button(label = "Bake Selected\nBy Last Object", command = self.BakeSelectedByLastObject, backgroundColor = Colors.orange100, annotation = ToolsAnnotations.bakeByLast) - - - # ANIMATION + def UILayoutAnimation(self, layoutMain, windowWidthMargin, lineHeight): layoutRigging = cmds.frameLayout(parent = layoutMain, label = "ANIMATION", collapsable = True) + layoutColumn = cmds.columnLayout(parent = layoutRigging, adjustableColumn = True) # - countOffsets = 3 - cmds.gridLayout(parent = layoutRigging, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) - cmds.button(label = "Delete\nAnimation", command = Other.DeleteKeys, backgroundColor = Colors.red100, annotation = ToolsAnnotations.deleteAnimation) - cmds.button(label = "Delete\nKey Range", command = Other.DeleteKeyRange, backgroundColor = Colors.red50, annotation = ToolsAnnotations.deleteKeyRange) - cmds.button(label = "Delete\nNonkeyable Keys", command = Other.KeysNonkeyableDelete, backgroundColor = Colors.red10, annotation = ToolsAnnotations.deleteNonkeyableKeys) + countOffsets = 4 + cmds.gridLayout(parent = layoutColumn, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.button(label = "Delete\nAnimation", command = Animation.DeleteKeys, backgroundColor = Colors.red100, annotation = ToolsAnnotations.deleteAnimation) + cmds.button(label = "Delete\nKey Range", command = Animation.DeleteKeyRange, backgroundColor = Colors.red50, annotation = ToolsAnnotations.deleteKeyRange) + cmds.button(label = "Delete\nNonkeyable", command = Animation.DeleteKeysNonkeyable, backgroundColor = Colors.red10, annotation = ToolsAnnotations.deleteNonkeyableKeys) + cmds.button(label = "Delete\nStatic", command = Animation.DeleteStaticCurves, backgroundColor = Colors.blackWhite80, annotation = ToolsAnnotations.deleteStaticCurves) + # + countOffsets = 1 + cmds.gridLayout(parent = layoutColumn, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.button(label = "Euler Filter", command = Animation.FilterCurve, backgroundColor = Colors.yellow10, annotation = ToolsAnnotations.filterCurve) + # + countOffsets = 5 + cmds.gridLayout(parent = layoutColumn, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.button(label = "Constant", command = partial(Animation.SetInfinity, 1, None), backgroundColor = Colors.blue10, annotation = ToolsAnnotations.animationCurveInfinity) + cmds.button(label = "Linear", command = partial(Animation.SetInfinity, 2, None), backgroundColor = Colors.blue10, annotation = ToolsAnnotations.animationCurveInfinity) + cmds.button(label = "Cycle", command = partial(Animation.SetInfinity, 3, None), backgroundColor = Colors.blue50, annotation = ToolsAnnotations.animationCurveInfinity) + cmds.button(label = "Offset", command = partial(Animation.SetInfinity, 4, None), backgroundColor = Colors.blue50, annotation = ToolsAnnotations.animationCurveInfinity) + cmds.button(label = "Oscillate", command = partial(Animation.SetInfinity, 5, None), backgroundColor = Colors.blue100, annotation = ToolsAnnotations.animationCurveInfinity) # countOffsets = 7 - cmds.gridLayout(parent = layoutRigging, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) + cmds.gridLayout(parent = layoutColumn, numberOfColumns = countOffsets, cellWidth = windowWidthMargin / countOffsets, cellHeight = lineHeight) cmds.button(label = "<<", command = partial(Timeline.SetTime, 3), backgroundColor = Colors.green10, annotation = ToolsAnnotations.timelineSetMinOuter) - cmds.button(label = "<", command = partial(Timeline.SetTime, 1), backgroundColor = Colors.lightBlue10, annotation = ToolsAnnotations.timelineSetMinInner) - cmds.button(label = ">", command = partial(Timeline.SetTime, 2), backgroundColor = Colors.lightBlue10, annotation = ToolsAnnotations.timelineSetMaxInner) + cmds.button(label = "<", command = partial(Timeline.SetTime, 1), backgroundColor = Colors.green50, annotation = ToolsAnnotations.timelineSetMinInner) + cmds.button(label = ">", command = partial(Timeline.SetTime, 2), backgroundColor = Colors.green50, annotation = ToolsAnnotations.timelineSetMaxInner) cmds.button(label = ">>", command = partial(Timeline.SetTime, 4), backgroundColor = Colors.green10, annotation = ToolsAnnotations.timelineSetMaxOuter) - cmds.button(label = "OUTER", command = partial(Timeline.SetTime, 5), backgroundColor = Colors.blue10, annotation = ToolsAnnotations.timelineExpandOuter) - cmds.button(label = "INNER", command = partial(Timeline.SetTime, 6), backgroundColor = Colors.blue10, annotation = ToolsAnnotations.timelineExpandInner) - cmds.button(label = "FOCUS", command = partial(Timeline.SetTime, 7), backgroundColor = Colors.orange10, annotation = ToolsAnnotations.timelineFocusRange) + cmds.button(label = "OUTER", command = partial(Timeline.SetTime, 5), backgroundColor = Colors.orange10, annotation = ToolsAnnotations.timelineExpandOuter) + cmds.button(label = "INNER", command = partial(Timeline.SetTime, 6), backgroundColor = Colors.orange10, annotation = ToolsAnnotations.timelineExpandInner) + cmds.button(label = "FOCUS", command = partial(Timeline.SetTime, 7), backgroundColor = Colors.orange50, annotation = ToolsAnnotations.timelineFocusRange) # LOCATORS def CreateLocator(self, *args): - Locators.Create(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocators = self.checkboxLocatorSubLocator.Get()) + Locators.Create(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocator = self.checkboxLocatorSubLocator.Get()) def CreateLocatorMatch(self, *args): - Locators.CreateOnSelected(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocators = self.checkboxLocatorSubLocator.Get()) + Locators.CreateOnSelected(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocator = self.checkboxLocatorSubLocator.Get()) def CreateLocatorParent(self, *args): - Locators.CreateOnSelectedWithParentConstrain(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocators = self.checkboxLocatorSubLocator.Get()) + Locators.CreateOnSelectedWithParentConstrain(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocator = self.checkboxLocatorSubLocator.Get()) def CreateLocatorBake(self, *args): - Locators.CreateOnSelectedAndBake(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocators = self.checkboxLocatorSubLocator.Get()) + Locators.CreateOnSelectedAndBake(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocator = self.checkboxLocatorSubLocator.Get()) def CreateLocatorBakeReverse(self, *args): - Locators.CreateOnSelectedReverseConstrain(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocators = self.checkboxLocatorSubLocator.Get()) + Locators.CreateOnSelectedReverseConstrain(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocator = self.checkboxLocatorSubLocator.Get()) def BakeAsChildrenFromLastSelected(self, *args): - Locators.BakeAsChildrenFromLastSelected(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocators = self.checkboxLocatorSubLocator.Get()) + Locators.BakeAsChildrenFromLastSelected(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocator = self.checkboxLocatorSubLocator.Get()) def BakeAsChildrenFromLastSelectedReverseSkipLast(self, *args): - Locators.BakeAsChildrenFromLastSelectedReverse(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocators = self.checkboxLocatorSubLocator.Get(), skipLastReverse = True) + Locators.BakeAsChildrenFromLastSelectedReverse(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocator = self.checkboxLocatorSubLocator.Get(), skipLastReverse = True) def BakeAsChildrenFromLastSelectedReverse(self, *args): - Locators.BakeAsChildrenFromLastSelectedReverse(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocators = self.checkboxLocatorSubLocator.Get(), skipLastReverse = False) + Locators.BakeAsChildrenFromLastSelectedReverse(scale = self.floatLocatorSize.Get(), hideParent = self.checkboxLocatorHideParent.Get(), subLocator = self.checkboxLocatorSubLocator.Get(), skipLastReverse = False) + def CreateLocatorBakeAim(self, axis, reverse, *args): + scale = self.floatLocatorSize.Get() + distance = self.floatLocatorAimOffset.Get() + hideParent = self.checkboxLocatorHideParent.Get() + subLocators = self.checkboxLocatorSubLocator.Get() + + if (axis == 1): axisVector = (-1, 0, 0) + elif (axis == 2): axisVector = (1, 0, 0) + elif (axis == 3): axisVector = (0, -1, 0) + elif (axis == 4): axisVector = (0, 1, 0) + elif (axis == 5): axisVector = (0, 0, -1) + elif (axis == 6): axisVector = (0, 0, 1) + + Locators.CreateOnSelectedAim(scale = scale, hideParent = hideParent, subLocator = subLocators, aimVector = axisVector, distance = distance, reverse = reverse) + + if (distance == 0): + cmds.warning("Aim distance is 0. Hihgly recomended to use non-zero value.") - # BAKER + # BAKING def BakeSelectedClassic(self, *args): Baker.BakeSelected(classic = True, preserveOutsideKeys = True) def BakeSelectedClassicCut(self, *args): diff --git a/GETOOLS_SOURCE/utils/Animation.py b/GETOOLS_SOURCE/utils/Animation.py new file mode 100644 index 0000000..7648075 --- /dev/null +++ b/GETOOLS_SOURCE/utils/Animation.py @@ -0,0 +1,54 @@ +# Copyright 2023 by Eugene Gataulin (GenEugene). All Rights Reserved. + +import maya.cmds as cmds +import maya.mel as mel + +from GETOOLS_SOURCE.utils import Selector + + +def DeleteKeys(*args): + if (Selector.MultipleObjects(1) == None): + return + cmds.cutKey() + +def DeleteKeyRange(*args): + mel.eval('timeSliderClearKey') + +def DeleteKeysNonkeyable(*args): + selected = cmds.ls(selection = True) + counter = 0 + for item in selected: + attributes = cmds.listAttr(item, channelBox = 1) + if attributes != None: + for j in range(len(attributes)): + cmds.cutKey(item + "." + attributes[j]) + counter += 1 + print ("\nNonkeyable attributes deleted: {0}".format(counter)) + +def DeleteStaticCurves(*args): + cmds.delete(staticChannels = True) + +def FilterCurve(*args): + cmds.filterCurve() + +def SetInfinity(mode, items = None, *args): + result = "" + if (mode == 1): + result = "constant" + elif (mode == 2): + result = "linear" + elif (mode == 3): + result = "cycle" + elif (mode == 4): + result = "cycleRelative" + elif (mode == 5): + result = "oscillate" + if (items == None): + cmds.setInfinity(preInfinite = result, postInfinite = result) + else: + cmds.setInfinity(items, preInfinite = result, postInfinite = result) +def SetInfinityConstant(selected): + SetInfinity(mode = 1, items = selected) +def SetInfinityCycle(selected): + SetInfinity(mode = 2, items = selected) + diff --git a/GETOOLS_SOURCE/utils/Baker.py b/GETOOLS_SOURCE/utils/Baker.py index d84a890..37a807f 100644 --- a/GETOOLS_SOURCE/utils/Baker.py +++ b/GETOOLS_SOURCE/utils/Baker.py @@ -21,8 +21,9 @@ def BakeSelected(classic = True, preserveOutsideKeys = True): print(timeMinMax) + cmds.refresh(suspend = True) if (classic): - cmds.bakeResults(time = (timeMinMax[0], timeMinMax[1]), preserveOutsideKeys = preserveOutsideKeys, simulation = True) + cmds.bakeResults(time = (timeMinMax[0], timeMinMax[1]), preserveOutsideKeys = preserveOutsideKeys, simulation = True, minimizeRotation = True) else: timeCurrent = Timeline.GetTimeCurrent() timeMinMax[1] = timeMinMax[1] + 1 @@ -33,6 +34,7 @@ def BakeSelected(classic = True, preserveOutsideKeys = True): if (not preserveOutsideKeys): cmds.cutKey(time = (None, timeMinMax[0] - 1)) # to left cmds.cutKey(time = (timeMinMax[1], None)) # to right + cmds.refresh(suspend = False) def BakeSelectedByLastObject(pairOnly = False): # Check selected objects @@ -53,12 +55,7 @@ def BakeSelectedByLastObject(pairOnly = False): BakeSelected() # Delete constraints - for i in range(len(selectedList)): - if (i == len(selectedList) - 1): - break - children = cmds.listRelatives(selectedList[i], type = "constraint") - for child in children: - cmds.delete(child) + Constraints.DeleteConstraints(selectedList, skipLast = True) cmds.select(selectedList) return selectedList diff --git a/GETOOLS_SOURCE/utils/Colors.py b/GETOOLS_SOURCE/utils/Colors.py index 5ace4cf..193c8c9 100644 --- a/GETOOLS_SOURCE/utils/Colors.py +++ b/GETOOLS_SOURCE/utils/Colors.py @@ -43,10 +43,10 @@ import maya.cmds as cmds -class ColorsCalibration: +class ColorsPalette: def __init__(self): self.window_name = "windowColorCalibration" - self.titleText = "Color Calibration" + self.titleText = "Colors Palette" self.windowWidth = 330 self.windowHeight = 10 self.lineHeight = 20 @@ -59,8 +59,7 @@ def CreateUI(self): cmds.window(self.window_name, edit = True, resizeToFitChildren = True) layoutMain = cmds.columnLayout(adjustableColumn = False, width = self.windowWidth) - - # CENTER OF MASS LOCATOR + # TODO add color console print on button press buttonsBlackWhite = 11 cmds.gridLayout(parent = layoutMain, numberOfColumns = buttonsBlackWhite, cellWidth = self.windowWidth / buttonsBlackWhite) # @@ -110,5 +109,3 @@ def CreateUI(self): # RUN WINDOW cmds.showWindow(self.window_name) -# colorCalibration = ColorsCalibration() -# colorCalibration.CreateUI() \ No newline at end of file diff --git a/GETOOLS_SOURCE/utils/Constraints.py b/GETOOLS_SOURCE/utils/Constraints.py index 9fb28e5..e83ae42 100644 --- a/GETOOLS_SOURCE/utils/Constraints.py +++ b/GETOOLS_SOURCE/utils/Constraints.py @@ -2,16 +2,16 @@ import maya.cmds as cmds +# from GETOOLS_SOURCE.utils import Locators from GETOOLS_SOURCE.utils import Selector -def ConstrainSelectedToLastObject(reverse=False, maintainOffset=True, parent=True, point=False, orient=False, scale=False, weight=1): - # Check selected objects +def ConstrainSelectedToLastObject(reverse=False, maintainOffset=True, parent=True, point=False, orient=False, scale=False, aim=False, weight=1): selected = Selector.MultipleObjects(2) if (selected == None): return - ConstrainListToLastElement(reverse, selected, maintainOffset, parent, point, orient, scale, weight) + ConstrainListToLastElement(reverse, selected, maintainOffset, parent, point, orient, scale, aim, weight) -def ConstrainListToLastElement(reverse=False, selected=None, maintainOffset=True, parent=True, point=False, orient=False, scale=False, weight=1): +def ConstrainListToLastElement(reverse=False, selected=None, maintainOffset=True, parent=True, point=False, orient=False, scale=False, aim=False, weight=1): if (selected == None): cmds.warning("### WARNING ### selected = None") return @@ -27,15 +27,14 @@ def ConstrainListToLastElement(reverse=False, selected=None, maintainOffset=True index1 = -1 index2 = i - ConstrainSecondToFirstObject(selected[index1], selected[index2], maintainOffset, parent, point, orient, scale, weight = weight) + ConstrainSecondToFirstObject(selected[index1], selected[index2], maintainOffset, parent, point, orient, scale, aim, weight = weight) -def ConstrainSecondToFirstObject(objectParent, objectChild, maintainOffset=True, parent=True, point=False, orient=False, scale=False, weight=1): +def ConstrainSecondToFirstObject(objectParent, objectChild, maintainOffset=True, parent=True, point=False, orient=False, scale=False, aim=False, weight=1): if parent: try: cmds.parentConstraint(objectParent, objectChild, maintainOffset = maintainOffset, weight = weight) except: print("||||| Can't create parentConstraint on {0}".format(objectChild)) - else: if point: try: @@ -55,4 +54,26 @@ def ConstrainSecondToFirstObject(objectParent, objectChild, maintainOffset=True, cmds.scaleConstraint(objectParent, objectChild, maintainOffset = maintainOffset) # weight = weight except: print("||||| Can't create scaleConstraint on {0}".format(objectChild)) + + if aim: + ConstrainAim(objectParent, objectChild, maintainOffset, weight) # TODO add customization logic + +def ConstrainAim(objectParent, objectChild, maintainOffset = True, weight = 1, aimVector = (0, 0, 1), upVector = (0, 1, 0), worldUpVector = (0, 1, 0), worldUpObject = None): # TODO complete aim logic + # "scene" "object" "objectrotation" "vector" "none" + if (worldUpObject == None): + cmds.aimConstraint(objectParent, objectChild, maintainOffset = maintainOffset, weight = weight, aimVector = aimVector, upVector = upVector, worldUpType = "vector", worldUpVector = worldUpVector) + else: + cmds.aimConstraint(objectParent, objectChild, maintainOffset = maintainOffset, weight = weight, aimVector = aimVector, upVector = upVector, worldUpType = "objectrotation", worldUpVector = worldUpVector, worldUpObject = worldUpObject) + +def DeleteConstraints(selected, skipLast = False): + count = len(selected) + + for i in range(count): + if (skipLast and i == count - 1): + break + + children = cmds.listRelatives(selected[i], type = "constraint") + if (children != None): + for child in children: + cmds.delete(child) diff --git a/GETOOLS_SOURCE/utils/Locators.py b/GETOOLS_SOURCE/utils/Locators.py index 3ff7188..9348c66 100644 --- a/GETOOLS_SOURCE/utils/Locators.py +++ b/GETOOLS_SOURCE/utils/Locators.py @@ -2,6 +2,7 @@ import maya.cmds as cmds +from GETOOLS_SOURCE.utils import Animation from GETOOLS_SOURCE.utils import Baker from GETOOLS_SOURCE.utils import Constraints from GETOOLS_SOURCE.utils import Parent @@ -10,9 +11,15 @@ # TODO think how to merge the same logic on each function. Looks like a lot of similar parts of code +nameBase = "gLoc" +nameMatched = "{0}Matched".format(nameBase) +nameConstrained = "{0}Constrained".format(nameBase) +nameBaked = "{0}Baked".format(nameBase) +nameReverse = "{0}Reverse".format(nameBase) +nameAim = "{0}Aim".format(nameBase) scale = 1.0 -def Create(name = "myLoc", scale = scale, hideParent = False, subLocators = False): +def Create(name = nameBase, scale = scale, hideParent = False, subLocator = False): locatorCurrent = cmds.spaceLocator(name = Text.SetUniqueFromText(name))[0] cmds.setAttr(locatorCurrent + "Shape.localScaleX", scale) cmds.setAttr(locatorCurrent + "Shape.localScaleY", scale) @@ -22,7 +29,7 @@ def Create(name = "myLoc", scale = scale, hideParent = False, subLocators = Fals if hideParent: cmds.setAttr(locatorCurrent + "Shape" + ".visibility", 0) - if (subLocators): + if subLocator: subLocator = Create(locatorCurrent + "Secondary") cmds.setAttr(subLocator + "Shape.localScaleX", scale) cmds.setAttr(subLocator + "Shape.localScaleY", scale) @@ -33,7 +40,7 @@ def Create(name = "myLoc", scale = scale, hideParent = False, subLocators = Fals else: return locatorCurrent -def CreateOnSelected(name = "myLocMatched", scale = scale, minSelectedCount = 1, hideParent = False, subLocators = False): +def CreateOnSelected(name = nameMatched, scale = scale, minSelectedCount = 1, hideParent = False, subLocator = False): # Check selected objects selectedList = Selector.MultipleObjects(minSelectedCount) if (selectedList == None): @@ -43,10 +50,10 @@ def CreateOnSelected(name = "myLocMatched", scale = scale, minSelectedCount = 1, locatorsList = [] sublocatorsList = [] for item in selectedList: - nameCurrent = Text.GetShortName(item, removeSpaces = True) + name - created = Create(name = nameCurrent, scale = scale, hideParent = hideParent, subLocators = subLocators) + nameCurrent = Text.GetShortName(item, removeSpaces = True) + "_" + name + created = Create(name = nameCurrent, scale = scale, hideParent = hideParent, subLocator = subLocator) - if (subLocators): + if subLocator: locatorsList.append(created[0]) sublocatorsList.append(created[1]) else: @@ -62,22 +69,22 @@ def CreateOnSelected(name = "myLocMatched", scale = scale, minSelectedCount = 1, cmds.matchTransform(locatorsList[-1], item, position = True, rotation = True, scale = True) # Select objects and return - if (subLocators): + if subLocator: cmds.select(sublocatorsList) return selectedList, locatorsList, sublocatorsList else: cmds.select(locatorsList) return selectedList, locatorsList -def CreateOnSelectedWithParentConstrain(name = "myLocConstrained", scale = scale, minSelectedCount = 1, hideParent = False, subLocators = False): - objects = CreateOnSelected(name = name, scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocators = subLocators) +def CreateOnSelectedWithParentConstrain(name = nameConstrained, scale = scale, minSelectedCount = 1, hideParent = False, subLocator = False): + objects = CreateOnSelected(name = name, scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocator = subLocator) if (objects == None): return None # Get lists from function selectedList = objects[0] locatorsList = objects[1] - if (subLocators): + if subLocator: sublocatorsList = objects[2] # Constrain locators @@ -85,27 +92,27 @@ def CreateOnSelectedWithParentConstrain(name = "myLocConstrained", scale = scale Constraints.ConstrainSecondToFirstObject(selectedList[i], locatorsList[i], maintainOffset = False) # Select objects and return - if (subLocators): + if subLocator: cmds.select(sublocatorsList) return selectedList, locatorsList, sublocatorsList else: cmds.select(locatorsList) return selectedList, locatorsList -def CreateOnSelectedAndBake(name = "myLocBaked", scale = scale, minSelectedCount = 1, hideParent = False, subLocators = False, parentToLastSelected = False): - objects = CreateOnSelectedWithParentConstrain(name = name, scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocators = subLocators) +def CreateOnSelectedAndBake(name = nameBaked, scale = scale, minSelectedCount = 1, hideParent = False, subLocator = False, parentToLastSelected = False): + objects = CreateOnSelectedWithParentConstrain(name = name, scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocator = subLocator) if (objects == None): return None # Get lists from function selectedList = objects[0] locatorsList = objects[1] - if (subLocators): + if subLocator: sublocatorsList = objects[2] # Parent locators to last or to last sublocator if (parentToLastSelected): - if (subLocators): + if subLocator: locatorsListWithLastSub = locatorsList[:-1] locatorsListWithLastSub.append(sublocatorsList[-1]) Parent.ListToLastObjects(locatorsListWithLastSub) @@ -115,89 +122,164 @@ def CreateOnSelectedAndBake(name = "myLocBaked", scale = scale, minSelectedCount # Bake locators and delete constraints cmds.select(locatorsList) Baker.BakeSelected() - for locator in locatorsList: - children = cmds.listRelatives(locator, type = "constraint") - for child in children: - cmds.delete(child) + Animation.DeleteStaticCurves() + Constraints.DeleteConstraints(locatorsList) # Select objects and return - if (subLocators): + if subLocator: cmds.select(sublocatorsList) return selectedList, locatorsList, sublocatorsList else: cmds.select(locatorsList) return selectedList, locatorsList -def CreateOnSelectedReverseConstrain(name = "myLocReverse", scale = scale, minSelectedCount = 1, hideParent = False, subLocators = False): - objects = CreateOnSelectedAndBake(name = name, scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocators = subLocators) +def CreateOnSelectedReverseConstrain(name = nameReverse, scale = scale, minSelectedCount = 1, hideParent = False, subLocator = False): + objects = CreateOnSelectedAndBake(name = name, scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocator = subLocator) if (objects == None): return None # Get lists from function selectedList = objects[0] locatorsList = objects[1] - if (subLocators): + if subLocator: sublocatorsList = objects[2] # Constrain objects to locators for i in range(len(selectedList)): - if (subLocators): + if subLocator: Constraints.ConstrainSecondToFirstObject(sublocatorsList[i], selectedList[i], maintainOffset = False) else: Constraints.ConstrainSecondToFirstObject(locatorsList[i], selectedList[i], maintainOffset = False) # Select objects and return - if (subLocators): + if subLocator: cmds.select(sublocatorsList) return selectedList, locatorsList, sublocatorsList else: cmds.select(locatorsList) return selectedList, locatorsList -def BakeAsChildrenFromLastSelected(scale = scale, minSelectedCount = 2, hideParent = False, subLocators = False): - objects = CreateOnSelectedAndBake(scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocators = subLocators, parentToLastSelected = True) +def BakeAsChildrenFromLastSelected(scale = scale, minSelectedCount = 2, hideParent = False, subLocator = False): + objects = CreateOnSelectedAndBake(scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocator = subLocator, parentToLastSelected = True) if (objects == None): return None # Get lists from function selectedList = objects[0] locatorsList = objects[1] - if (subLocators): + if subLocator: sublocatorsList = objects[2] # Select objects and return - if (subLocators): + if subLocator: cmds.select(sublocatorsList[-1]) return selectedList, locatorsList, sublocatorsList else: cmds.select(locatorsList[-1]) return objects -def BakeAsChildrenFromLastSelectedReverse(scale = scale, hideParent = False, subLocators = False, skipLastReverse = True): - objects = BakeAsChildrenFromLastSelected(scale = scale, hideParent = hideParent, subLocators = subLocators) +def BakeAsChildrenFromLastSelectedReverse(scale = scale, hideParent = False, subLocator = False, skipLastReverse = True): + objects = BakeAsChildrenFromLastSelected(scale = scale, hideParent = hideParent, subLocator = subLocator) if (objects == None): return None # Get lists from function selectedList = objects[0] locatorsList = objects[1] - if (subLocators): + if subLocator: sublocatorsList = objects[2] # Constrain objects to locators for i in range(len(objects[0])): if (skipLastReverse and i == len(selectedList) - 1): break - if (subLocators): + if subLocator: Constraints.ConstrainSecondToFirstObject(sublocatorsList[i], selectedList[i], maintainOffset = False) else: Constraints.ConstrainSecondToFirstObject(locatorsList[i], selectedList[i], maintainOffset = False) # Select objects and return - if (subLocators): + if subLocator: cmds.select(sublocatorsList[-1]) return selectedList, locatorsList, sublocatorsList else: cmds.select(locatorsList[-1]) return objects +def CreateOnSelectedAim(name = nameAim, scale = scale, minSelectedCount = 1, hideParent = False, subLocator = False, aimVector = (1, 0, 0), distance = 100, reverse = True): + objects = CreateOnSelected(name = name, scale = scale, minSelectedCount = minSelectedCount, hideParent = hideParent, subLocator = subLocator) + if (objects == None): + return None + + # Get lists from function + selectedList = objects[0] + locatorsRootList = objects[1] + if subLocator: + sublocatorsList = objects[2] + + # Create aim locators + groupsList = [] + locatorsOffsetsList = [] + locatorsTargetsList = [] + for i in range(len(selectedList)): + aimGroup = cmds.group(empty = True, name = selectedList[i] + "_AimGroup") + locOffset = Create(name = locatorsRootList[i] + "Offset", scale = scale) + locTarget = Create(name = locatorsRootList[i] + "Target", scale = scale) + + cmds.matchTransform(locOffset, locatorsRootList[i], position = True, rotation = True, scale = True) + cmds.matchTransform(locTarget, locatorsRootList[i], position = True, rotation = True, scale = True) + + cmds.parent(locatorsRootList[i], aimGroup) + cmds.parent(locOffset, locatorsRootList[i]) + cmds.parent(locTarget, aimGroup) + + if subLocator: + cmds.matchTransform(sublocatorsList[i], locOffset, position = True, rotation = True, scale = True) + cmds.parent(sublocatorsList[i], locOffset) + + aimVectorScaled = [0, 0, 0] + aimVectorScaled[0] = aimVector[0] * distance + aimVectorScaled[1] = aimVector[1] * distance + aimVectorScaled[2] = aimVector[2] * distance + cmds.move(aimVectorScaled[0], aimVectorScaled[1], aimVectorScaled[2], locTarget, relative = True, objectSpace = True, worldSpaceDistance = True) + + groupsList.append(aimGroup) + locatorsOffsetsList.append(locOffset) + locatorsTargetsList.append(locTarget) + + Constraints.ConstrainListToLastElement(selected = (locatorsRootList[i], selectedList[i]), parent = False, point = True, orient = True) + Constraints.ConstrainListToLastElement(selected = (locTarget, selectedList[i])) + + # Bake animation from original objects + cmds.select(locatorsRootList + locatorsTargetsList, replace = True) + Baker.BakeSelected() + Constraints.DeleteConstraints(locatorsRootList) + Constraints.DeleteConstraints(locatorsTargetsList) + Animation.DeleteStaticCurves() + + # Create aim constraint + for i in range(len(selectedList)): + if (aimVector[2] == 0): + upVector = (0, 0, 1) + else: + upVector = (0, 1, 0) + cmds.aimConstraint(locatorsTargetsList[i], locatorsOffsetsList[i], maintainOffset = True, weight = 1, aimVector = aimVector, upVector = upVector, worldUpType = "objectrotation", worldUpVector = upVector, worldUpObject = locatorsRootList[i]) + + # Reverse constrain # TODO move constraint to temp group + if (reverse): + for i in range(len(selectedList)): + parentObject = None + if subLocator: + parentObject = sublocatorsList[i] + else: + parentObject = locatorsOffsetsList[i] + + Constraints.ConstrainSecondToFirstObject(parentObject, selectedList[i], maintainOffset = False, parent = False, point = True, orient = True) + + # Select objects and return + cmds.select(locatorsTargetsList) + if subLocator: + return selectedList, aimGroup, locatorsRootList, locatorsOffsetsList, locatorsTargetsList, sublocatorsList + else: + return selectedList, aimGroup, locatorsRootList, locatorsOffsetsList, locatorsTargetsList + diff --git a/GETOOLS_SOURCE/utils/Other.py b/GETOOLS_SOURCE/utils/Other.py index 9f41d1b..9eecfd3 100644 --- a/GETOOLS_SOURCE/utils/Other.py +++ b/GETOOLS_SOURCE/utils/Other.py @@ -1,9 +1,9 @@ # Copyright 2023 by Eugene Gataulin (GenEugene). All Rights Reserved. import maya.cmds as cmds -import maya.mel as mel +# import maya.mel as mel -from GETOOLS_SOURCE.utils import Selector +# from GETOOLS_SOURCE.utils import Selector def RotateOrderVisibility(on = True, *args): selected = cmds.ls(selection = True, type = "transform") @@ -20,31 +20,7 @@ def JointDrawStyle(mode = 0, *args): for item in selected: cmds.setAttr(item + ".drawStyle", mode) -def DeleteKeys(*args): - if (Selector.MultipleObjects(1) == None): - return - cmds.cutKey() - -def DeleteKeyRange(*args): - mel.eval('timeSliderClearKey') - -def KeysNonkeyableDelete(*args): - selected = cmds.ls(selection = True) - counter = 0 - for item in selected: - attributes = cmds.listAttr(item, channelBox = 1) - if attributes != None: - for j in range(len(attributes)): - cmds.cutKey(item + "." + attributes[j]) - counter += 1 - print ("\nNonkeyable attributes deleted: {0}".format(counter)) - def SelectJointsInScene(): # TODO make universal for other types selected = cmds.ls(type = "joint") cmds.select(selected) -def SetInfinityConstant(selected): # TODO move to new animation class and expose - cmds.setInfinity(selected, preInfinite = "constant", postInfinite = "constant") - -def SetInfinityCycle(selected): # TODO move to new animation class and expose - cmds.setInfinity(selected, preInfinite = "cycle", postInfinite = "cycle") \ No newline at end of file diff --git a/GETOOLS_SOURCE/utils/UI.py b/GETOOLS_SOURCE/utils/UI.py index c788cda..3186224 100644 --- a/GETOOLS_SOURCE/utils/UI.py +++ b/GETOOLS_SOURCE/utils/UI.py @@ -54,7 +54,7 @@ class Checkbox: def __init__(self, label = "label", value = False, - enabled = True, + enable = True, annotation = "", command = "pass", # commandResetAll = "", @@ -62,7 +62,7 @@ def __init__(self, ): self.valueDefault = value - self.checkbox = cmds.checkBox(label = label, value = value, changeCommand = command, enable = enabled, annotation = annotation) + self.checkbox = cmds.checkBox(label = label, value = value, changeCommand = command, enable = enable, annotation = annotation) if (menuReset): cmds.popupMenu() @@ -146,12 +146,14 @@ def Set(self, value = None, *args): else: cmds.button(self.marker, edit = True, backgroundColor = self.markerColorDefault) - self.command() + if(self.command != "pass"): + self.command() def Reset(self, *args): cmds.button(self.marker, edit = True, backgroundColor = self.markerColorDefault) cmds.floatSliderGrp(self.slider, edit = True, value = self.valueDefault) - self.command() + if(self.command != "pass"): + self.command() # def Scan(self, *args): # TODO rework or remove # _firstName = _OVERLAPPY.selected diff --git a/GETOOLS_SOURCE/values/Types.py b/GETOOLS_SOURCE/values/Types.py index fb7099e..2194bf7 100644 --- a/GETOOLS_SOURCE/values/Types.py +++ b/GETOOLS_SOURCE/values/Types.py @@ -57,4 +57,12 @@ ".trailDrawMode" ".template" "snapshotShape" -".pts" \ No newline at end of file +".pts" + +# Animation curve infinity +infinityConstant = "constant" +infinityLinear = "linear" +infinityCycle = "cycle" +infinityCycleRelative = "cycleRelative" +infinityOscillate = "oscillate" + diff --git a/changelog.txt b/changelog.txt index 130af43..92754d9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,11 +1,27 @@ GETools changelog +Backlog: +- in progress | [RIGGING] added constraint offset object +- in progress | [RIGGING] added Aim Constraint logic + +v0.0.11 +- [UI] moved Select Transform Hierarchy button to Utils menu and remove SELECT category in TOOLS module +- [UI] changed window width, margins and spacing between ui elements +- [UI] added Color Palette window for colors analysis +- [UI] added toggling for script window execution. Press the same button to open/close script (reset all parameters changes) +- [TOOLS] added Locators baking to Aim space +- [TOOLS] added Infinity buttons for animation curves +- [TOOLS] added delete static curves button +- [TOOLS] added curve euler filter +- [RIGGING] added Delete Constraints button +- extracted Animation functions from Other module into separate module +- improved baking speed + v0.0.10 - [TOOLS] added custom bake cut outside logic - [TOOLS] added float field for locator scale - [UI] extracted rigging module from Tools and created new Rigging category - [UI] moved "Print selected objects to console" button from Tools/Select to Utils pop-up menu -- v0.0.9 - reinstall required - [CRITICAL] fixed support for Maya 2020, removed circular dependencies