Files
2025-09-29 00:52:08 +02:00

4021 lines
125 KiB
Python
Executable File

'''
From https://github.com/Danlowlows/MobuCore
Adjustment Blending is a method for adjusting additive layer interpolation between keyframes, so that movement on the layer is shifted to areas where there is already movement on the base layer.
This helps to maintain the existing energy of the base layer motion, and helps to maintain contact points. For more information, see this talk from GDC 2016: https://youtu.be/eeWBlMJHR14?t=518
MobuCoreLibrary functions are required for this script.
____________________________________________________________________
This script was written by Dan Lowe as part of the MobuCore package. You can reach Dan Lowe on Twitter at https://twitter.com/danlowlows (at time of writing, direct messages are open).
MobuCore is made available under the following license terms:
Copyright (c) 2019 Dan Lowe
This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
2. If you use this software, in source or binary form, an acknowledgment in the product documentation or credits would be appreciated but is not required. Example: "This product uses MobuCore (c) 2019 Dan Lowe."
3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
4. This notice may not be removed or altered from any source distribution.
'''
from pyfbsdk import *
# Gets all referened objects for a given character extension.
def GetObjectsFromExtension(ext):
extObjList = []
for i in range(ext.GetSrcCount()):
extObjList.append(ext.GetSrc(i))
if extObjList == []:
extObjList = None
return extObjList
# Gets all referenced character extension objects for a given character.
def GetCharacterExtensionObjects(character=None):
if not character:
character = FBApplication().CurrentCharacter
if character:
characterExtentionObjects = []
for ext in FBSystem().Scene.CharacterExtensions:
attachedChar = ext.PropertyList.Find("AttachedCharacter")
if len(attachedChar) > 0:
if attachedChar[0] == character:
extObjList = GetObjectsFromExtension(ext)
characterExtentionObjects = characterExtentionObjects + extObjList
if characterExtentionObjects == []:
characterExtentionObjects = None
else:
characterExtentionObjects = list(dict.fromkeys(characterExtentionObjects))
return characterExtentionObjects
# Gets the control rig for a given character.
def GetControlRigForCharacter(character=None):
if not character:
character = FBApplication().CurrentCharacter
if character:
ctrlRig = character.PropertyList.Find("ControlSet")
if len(ctrlRig) != 0:
ctrlRig = ctrlRig[0]
else:
ctrlRig = None
if ctrlRig:
return ctrlRig
# Get all character effectors and extensions.
def GetCharacterEffectorsAndExtensions(character=None):
if not character:
character = FBApplication().CurrentCharacter
if character:
effectors = GetControlRigEffectors(character)
extensions = GetCharacterExtensionObjects(character)
if not isinstance(effectors, list):
effectors = [effectors]
if not isinstance(extensions, list):
extensions = [extensions]
return effectors + extensions
# Gets the IK effectors for a given character.
def GetControlRigIKEffectors(character=None):
if not character:
character = FBApplication().CurrentCharacter
if character:
ctrlRig = GetControlRigForCharacter(character)
ikEffectors = []
for nodeId in FBEffectorId.values.itervalues():
if nodeId not in [FBEffectorId.kFBInvalidEffectorId, FBEffectorId.kFBLastEffectorId]:
effector = ctrlRig.GetIKEffectorModel(nodeId, 0)
if effector:
ikEffectors.append(effector)
if ikEffectors == []:
ikEffectors = None
return ikEffectors
# Gets the FK effectors for a given character.
def GetControlRigFKEffectors(character=None):
if not character:
character = FBApplication().CurrentCharacter
if character:
fkEffectors = []
for nodeId in FBBodyNodeId.values.itervalues():
if nodeId not in [FBBodyNodeId.kFBInvalidNodeId, FBBodyNodeId.kFBLastNodeId]:
effector = character.GetCtrlRigModel(nodeId)
if effector:
fkEffectors.append(effector)
if fkEffectors == []:
fkEffectors = None
return fkEffectors
# Gets both the FK and IK effectors for a given character.
def GetControlRigEffectors(character=None):
if not character:
character = FBApplication().CurrentCharacter
if character:
controlRigEffectors = GetControlRigFKEffectors(character) + GetControlRigIKEffectors(character)
return controlRigEffectors
# Groups pairs of keys from the layer fcurve, between which it will run an independent adjustment blend (allows adjustment blend to work with multiple key poses on the layer).
def GetKeyPairsFromFCurve(keys):
keyPairsList = []
for i in range(len(keys) - 1):
startKeyTime = keys[i].Time
startKeyValue = keys[i].Value
stopKeyTime = keys[i + 1].Time
stopKeyValue = keys[i + 1].Value
keyPairsList.append([startKeyTime, stopKeyTime, startKeyValue, stopKeyValue])
return keyPairsList
# Gets the transform nodes for an object.
def GetObjTransformNodes(obj):
transProp = obj.PropertyList.Find("Lcl Translation")
rotProp = obj.PropertyList.Find("Lcl Rotation")
if not transProp:
transProp.SetAnimated(True)
transProp = obj.PropertyList.Find("Lcl Translation")
if not rotProp:
rotProp.SetAnimated(True)
rotProp = obj.PropertyList.Find("Lcl Rotation")
transNodes = transProp.GetAnimationNode().Nodes
rotNodes = rotProp.GetAnimationNode().Nodes
nodes = list(transNodes) + list(rotNodes)
return nodes
# Gets the fcurves for an object from a specified layer.
def GetObjectFCurvesForLayer(obj, layerIndex):
FBSystem().CurrentTake.SetCurrentLayer(layerIndex)
try:
return [node.FCurve for node in GetObjTransformNodes(obj)]
except:
return []
# Reads the per frame values from an fcurve (doesn't require keys to be on those frames).
def EvaluateFCurveForKeyPairTimespan(fcurve, startTime, stopTime):
keyPairSpanValues = []
current = startTime
while not current > stopTime:
keyPairSpanValues.append([current, fcurve.Evaluate(current)])
current += FBTime(0, 0, 0, 1)
return keyPairSpanValues
# Finds the percentage of change that occured on the base layer curve, for the key pair.
def GetPercentageOfChangeValues(spanValues):
changeValues = [0.0]
for i in range(len(spanValues) - 1):
frameChangeValue = abs(spanValues[i + 1][1] - spanValues[i][1])
changeValues.append(frameChangeValue)
totalBaseLayerChange = sum(changeValues)
percentageValues = []
for i in range(len(changeValues)):
if totalBaseLayerChange != 0:
percentageValues.append([spanValues[i][0], (100.0 / totalBaseLayerChange) * changeValues[i]])
return percentageValues, totalBaseLayerChange
# The main adjustment blend function that does everything else. This is what you'd run if you were just adjustment blending a single object.
def AdjustmentBlendObject(obj):
take = FBSystem().CurrentTake
if take.GetLayerCount() > 1:
poseLayerFCurves = GetObjectFCurvesForLayer(obj, take.GetLayerCount() - 1)
baseLayerFCurves = GetObjectFCurvesForLayer(obj, 0)
for i in range(len(poseLayerFCurves)):
poseFCurve = poseLayerFCurves[i]
keys = poseFCurve.Keys
if len(keys) > 1:
keyPairsList = GetKeyPairsFromFCurve(keys)
for keyPair in keyPairsList:
startTime = keyPair[0]
stopTime = keyPair[1]
startValue = keyPair[2]
stopValue = keyPair[3]
spanValues = EvaluateFCurveForKeyPairTimespan(baseLayerFCurves[i], startTime, stopTime)
percentageValues, totalBaseLayerChange = GetPercentageOfChangeValues(spanValues)
totalPoseLayerChange = abs(stopValue - startValue)
previousValue = startValue
for value in percentageValues:
valueDelta = (totalPoseLayerChange / 100.0) * value[1]
if stopValue > startValue:
currentValue = previousValue + valueDelta
else:
currentValue = previousValue - valueDelta
poseLayerFCurves[i].KeyAdd(value[0], currentValue)
previousValue = currentValue
# The main adjustment blending function for running it on an entire character.
def AdjustmentBlendCharacter(character=None):
if not character:
character = FBApplication().CurrentCharacter
if character:
take = FBSystem().CurrentTake
if take.GetLayerCount() > 1:
characterObjs = GetCharacterEffectorsAndExtensions(character)
for obj in characterObjs:
if obj:
AdjustmentBlendObject(obj)
else:
FBMessageBox("Error...",
"No additive layer found for %s. Adjustment blending affects interpolation between keys on the the top most additive layer." % take.Name,
"OK")
else:
FBMessageBox("Error...",
"No additive layer found for %s. Adjustment blending affects interpolation between keys on the top most additive layer." % take.Name,
"OK")
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def run():
# -- Get number of takes selected
number_of_selected_takes = getNumberOfSelectedTakes()
# if there is one selected take, still ignore it and use the current take
# it's a bit annoying when you have one take selected different from the current - chances are the user didn't mean to.
if number_of_selected_takes > 1:
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
# go to take
FBSystem().CurrentTake = FBSystem().Scene.Takes[take_index]
AdjustmentBlendCharacter()
else:
AdjustmentBlendCharacter()
run()
import os
from RS import Perforce as P4
from pyfbsdk import *
import pythonidelib
def popUp(pUpTitle, pUpMessage, btn1="Continue", btn2="Cancel"):
input = FBMessageBox(pUpTitle,
pUpMessage,
btn1,
btn2
)
return input
def filename(path):
withext = str(path.split('\\')[-1])
withoutext = withext.split('.')[0]
return withoutext.upper()
def fileChecks(fbx):
fbxchecks = [False, False, False, False]
fbxinfo = P4.GetFileState(fbx)
if os.path.exists(fbx):
fbxchecks[0] = True
else:
popUp("Unable to Check Out", "Could not find the file locally")
if fbxchecks[0]:
if P4.DoesFileExist(fbx):
fbxchecks[1] = True
else:
if popUp("Unable to Check Out", "File does not exist in Perforce. Would you like to add it?") == 1:
CL = P4.CreateChangelist("[SOURCE] - " + filename(fbx))
P4.Add(fbx, CL.Number, True)
popUp("Checked Out", "FBX Added to CL %s" % CL.Number)
if fbxchecks[1]:
if not P4.IsOpenForEdit(fbxinfo):
fbxchecks[2] = True
else:
popUp("Unable to Check Out", "File is already Checked out")
if P4.IsLatest(fbxinfo):
fbxchecks[3] = True
else:
if popUp("Not Latest Revision", "You do not have the latest revision of this file. Get latest now?") == 1:
P4.Sync(fbx)
if all(fbxchecks) == True:
return True
else:
return False
if fileChecks(FBApplication().FBXFileName):
CL = P4.CreateChangelist("[SOURCE] - " + filename(FBApplication().FBXFileName))
P4.Edit(FBApplication().FBXFileName, CL.Number)
popUp("Checked Out", "FBX Checked out in CL %s" % CL.Number)
else:
print "Checks failed"
pythonidelib.FlushOutput()
#######################################################################
# -- Quickly reduce keys on all animated curves of selected models --
#######################################################################
from pyfbsdk import *
def reduceKeysOnSelected():
# Create a Key Reducing filter.
cleanFilter = FBFilterManager().CreateFilter('Key Reducing')
cleanFilter.PropertyList.Find('Precision').Data = 0.04
# -- Create an empty FBModelList
selectedModels = FBModelList()
topModel = None # -- Search all models, not just a particular branch
selectionState = True # -- Return models that are selected, not deselected
sortBySelectOrder = True # -- The last model in the list was selected most recently
FBGetSelectedModels(selectedModels, topModel, selectionState, sortBySelectOrder)
for model in selectedModels:
for lProp in model.PropertyList:
if lProp and lProp.IsAnimatable() and lProp.IsAnimated():
cleanFilter.Apply(lProp.GetAnimationNode(), True)
reduceKeysOnSelected()
#############################################################
# -- Quickly reduce all selected keys in the graph editor --
#############################################################
from pyfbsdk import *
import pythonidelib
pythonidelib.FlushOutput()
def getSelectedModels():
# -- Create an empty FBModelList
selectedModels = FBModelList()
topModel = None # -- Search all models, not just a particular branch
selectionState = True # -- Return models that are selected, not deselected
sortBySelectOrder = True # -- The last model in the list was selected most recently
FBGetSelectedModels(selectedModels, topModel, selectionState, sortBySelectOrder)
return selectedModels
def reduceSelectedKeys():
print "Starting Key Cleanup"
# -- Create a Key Reducing filter.
cleanFilter = FBFilterManager().CreateFilter( 'Key Reducing' )
cleanFilter.PropertyList.Find('Precision').Data = 0.04
# -- Create an empty list to be filled with nodes that have curves
nodesWithCurves = []
# -- Create an empty dictionary for storing keyframe times
selKeyTimes = {}
# -- Create an empty list of frame times
selKeyFrames = []
# -- For each model selected
for model in getSelectedModels():
# -- Find its properties
for lProp in model.PropertyList:
# -- For each property, find if it is animated
if lProp and lProp.IsAnimatable() and lProp.IsAnimated():
# ======== Finding Nodes capable of having FCurves =======
# -- If so, get the connected animation node
animNode = lProp.GetAnimationNode()
# -- Fine all children nodes of the connected animation node
nodes = animNode.Nodes
# -- If children nodes are found
if len(nodes) > 0:
# -- Add each one to our list
for node in nodes:
nodesWithCurves.append(node)
# -- Otherwise add the anim node to our list
else:
nodesWithCurves.append(animNode)
# ======== Finding Selected Keyframes ==========
# -- For every node in our list
for node in nodesWithCurves:
# -- reset the selected key times dictionary
selKeyTimes = {}
# -- If the node has an FCurve
if node.FCurve:
# -- For each keyframe on the FCurve
for key in node.FCurve.Keys:
# -- If that key is selected
if key.Selected == True:
# -- Add the keyframe's time to the dictionary
selKeyTimes[key.Time.GetFrame()] = key.Time
# -- If at least one keyframe was selected
if len(selKeyTimes) > 0:
# -- Fill the list with the frame data from the dictionary
for key in selKeyTimes:
selKeyFrames.append(key)
# -- Find the highest and lowest number in the frame list. This will be our filter range
startTime = min(selKeyFrames)
stopTime = max(selKeyFrames)
# -- Set the range of our filter using the range of selected keyframes
if startTime in selKeyTimes:
if stopTime in selKeyTimes:
cleanFilter.Start = selKeyTimes[startTime]
cleanFilter.Stop = selKeyTimes[stopTime]
# -- Apply the filter
cleanFilter.Apply(node.FCurve)
print "Cleaning keys on %s %s.%s from %r to %r" % (model.Name, animNode.Name, node.Name, startTime, stopTime)
# -- Cleanup
del (cleanFilter, nodesWithCurves, selKeyTimes, selKeyFrames)
print "Key Cleanup Complete"
reduceSelectedKeys()
################################################
# -- Lifted from Animal Tools created by Mangesh
################################################
from pyfbsdk import FBConstraintManager, FBModelList, FBGetSelectedModels
def renameConstraint(con):
if con.ReferenceGroupGetCount() in range(2,4):
child = con.ReferenceGet(0)
parent = con.ReferenceGet(1)
type = con.Description
if con.Description == 'Position From Positions':
type = 'Position'
elif con.Description == 'Rotation From Rotations':
type = 'Rotation'
elif con.Description == 'Scale From Scales':
type = 'Scale'
if child and parent:
newName = type + ' - ' + parent.Name + ' > ' + child.Name
con.Name = newName
else:
newName = type + ' - [EMPTY CONSTRAINT]'
con.Name = newName
def createConstraint():
selectedModels = FBModelList()
FBGetSelectedModels(selectedModels, None, True, True)
if len(selectedModels) <= 1 or len(selectedModels) > 2:
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Parent/Child")
return
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Parent/Child")
# get model & geometry
lMdls = FBModelList()
topModel = None
selectionState = True
sortBySelectOrder = True
FBGetSelectedModels(lMdls, topModel, selectionState, sortBySelectOrder)
mMdl = lMdls[1]
lGeo = lMdls[0]
# adding elements to the constraint slots
lConst.ReferenceAdd(0, mMdl)
lConst.ReferenceAdd(1, lGeo)
# weight of the constraint
lConst.Weight = 100
lConst.Active = False
lConst.Snap()
lConst.Lock = True
renameConstraint(lConst)
createConstraint()################################################
# -- Lifted from Animal Tools created by Mangesh
################################################
from pyfbsdk import FBConstraintManager, FBModelList, FBGetSelectedModels
def renameConstraint(con):
if con.ReferenceGroupGetCount() in range(2,4):
child = con.ReferenceGet(0)
parent = con.ReferenceGet(1)
type = con.Description
if con.Description == 'Position From Positions':
type = 'Position'
elif con.Description == 'Rotation From Rotations':
type = 'Rotation'
elif con.Description == 'Scale From Scales':
type = 'Scale'
if child and parent:
newName = type + ' - ' + parent.Name + ' > ' + child.Name
con.Name = newName
else:
newName = type + ' - [EMPTY CONSTRAINT]'
con.Name = newName
def createConstraint():
selectedModels = FBModelList()
FBGetSelectedModels(selectedModels, None, True, True)
if len(selectedModels) <= 1 or len(selectedModels) > 2:
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Parent/Child")
return
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Parent/Child")
# get model & geometry
lMdls = FBModelList()
topModel = None
selectionState = True
sortBySelectOrder = True
FBGetSelectedModels(lMdls, topModel, selectionState, sortBySelectOrder)
mMdl = lMdls[1]
lGeo = lMdls[0]
# adding elements to the constraint slots
lConst.ReferenceAdd(0, mMdl)
lConst.ReferenceAdd(1, lGeo)
# weight of the constraint
lConst.Weight = 100
lConst.Active = True
lConst.Lock = True
renameConstraint(lConst)
createConstraint()################################################
# -- Lifted from Animal Tools created by Mangesh
################################################
from pyfbsdk import FBConstraintManager, FBModelList, FBGetSelectedModels
def renameConstraint(con):
if con.ReferenceGroupGetCount() in range(2,4):
child = con.ReferenceGet(0)
parent = con.ReferenceGet(1)
type = con.Description
if con.Description == 'Position From Positions':
type = 'Position'
elif con.Description == 'Rotation From Rotations':
type = 'Rotation'
elif con.Description == 'Scale From Scales':
type = 'Scale'
if child and parent:
newName = type + ' - ' + parent.Name + ' > ' + child.Name
con.Name = newName
else:
newName = type + ' - [EMPTY CONSTRAINT]'
con.Name = newName
def createConstraint():
selectedModels = FBModelList()
FBGetSelectedModels(selectedModels, None, True, True)
if len(selectedModels) <= 1 or len(selectedModels) > 2:
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Position")
return
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Position")
# get model & geometry
lMdls = FBModelList()
topModel = None
selectionState = True
sortBySelectOrder = True
FBGetSelectedModels(lMdls, topModel, selectionState, sortBySelectOrder)
mMdl = lMdls[1]
lGeo = lMdls[0]
# adding elements to the constraint slots
lConst.ReferenceAdd(0, mMdl)
lConst.ReferenceAdd(1, lGeo)
# weight of the constraint
lConst.Weight = 100
lConst.Active = False
lConst.Snap()
lConst.Lock = True
renameConstraint(lConst)
createConstraint()################################################
# -- Lifted from Animal Tools created by Mangesh
################################################
from pyfbsdk import FBConstraintManager, FBModelList, FBGetSelectedModels
def renameConstraint(con):
if con.ReferenceGroupGetCount() in range(2,4):
child = con.ReferenceGet(0)
parent = con.ReferenceGet(1)
type = con.Description
if con.Description == 'Position From Positions':
type = 'Position'
elif con.Description == 'Rotation From Rotations':
type = 'Rotation'
elif con.Description == 'Scale From Scales':
type = 'Scale'
if child and parent:
newName = type + ' - ' + parent.Name + ' > ' + child.Name
con.Name = newName
else:
newName = type + ' - [EMPTY CONSTRAINT]'
con.Name = newName
def createConstraint():
selectedModels = FBModelList()
FBGetSelectedModels(selectedModels, None, True, True)
if len(selectedModels) <= 1 or len(selectedModels) > 2:
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Position")
return
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Position")
# get model & geometry
lMdls = FBModelList()
topModel = None
selectionState = True
sortBySelectOrder = True
FBGetSelectedModels(lMdls, topModel, selectionState, sortBySelectOrder)
mMdl = lMdls[1]
lGeo = lMdls[0]
# adding elements to the constraint slots
lConst.ReferenceAdd(0, mMdl)
lConst.ReferenceAdd(1, lGeo)
# weight of the constraint
lConst.Weight = 100
lConst.Active = True
lConst.Lock = True
renameConstraint(lConst)
createConstraint()################################################
# -- Lifted from Animal Tools created by Mangesh
################################################
from pyfbsdk import FBConstraintManager, FBModelList, FBGetSelectedModels
def renameConstraint(con):
if con.ReferenceGroupGetCount() in range(2,4):
child = con.ReferenceGet(0)
parent = con.ReferenceGet(1)
type = con.Description
if con.Description == 'Position From Positions':
type = 'Position'
elif con.Description == 'Rotation From Rotations':
type = 'Rotation'
elif con.Description == 'Scale From Scales':
type = 'Scale'
if child and parent:
newName = type + ' - ' + parent.Name + ' > ' + child.Name
con.Name = newName
else:
newName = type + ' - [EMPTY CONSTRAINT]'
con.Name = newName
def createConstraint():
selectedModels = FBModelList()
FBGetSelectedModels(selectedModels, None, True, True)
if len(selectedModels) <= 1 or len(selectedModels) > 2:
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Rotation")
return
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Rotation")
# get model & geometry
lMdls = FBModelList()
topModel = None
selectionState = True
sortBySelectOrder = True
FBGetSelectedModels(lMdls, topModel, selectionState, sortBySelectOrder)
mMdl = lMdls[1]
lGeo = lMdls[0]
# adding elements to the constraint slots
lConst.ReferenceAdd(0, mMdl)
lConst.ReferenceAdd(1, lGeo)
# weight of the constraint
lConst.Weight = 100
lConst.Active = False
lConst.Snap()
lConst.Lock = True
renameConstraint(lConst)
createConstraint()################################################
# -- Lifted from Animal Tools created by Mangesh
################################################
from pyfbsdk import FBConstraintManager, FBModelList, FBGetSelectedModels
def renameConstraint(con):
if con.ReferenceGroupGetCount() in range(2,4):
child = con.ReferenceGet(0)
parent = con.ReferenceGet(1)
type = con.Description
if con.Description == 'Position From Positions':
type = 'Position'
elif con.Description == 'Rotation From Rotations':
type = 'Rotation'
elif con.Description == 'Scale From Scales':
type = 'Scale'
if child and parent:
newName = type + ' - ' + parent.Name + ' > ' + child.Name
con.Name = newName
else:
newName = type + ' - [EMPTY CONSTRAINT]'
con.Name = newName
def createConstraint():
selectedModels = FBModelList()
FBGetSelectedModels(selectedModels, None, True, True)
if len(selectedModels) <= 1 or len(selectedModels) > 2:
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Rotation")
return
lMgr = FBConstraintManager()
lConst = lMgr.TypeCreateConstraint("Rotation")
# get model & geometry
lMdls = FBModelList()
topModel = None
selectionState = True
sortBySelectOrder = True
FBGetSelectedModels(lMdls, topModel, selectionState, sortBySelectOrder)
mMdl = lMdls[1]
lGeo = lMdls[0]
# adding elements to the constraint slots
lConst.ReferenceAdd(0, mMdl)
lConst.ReferenceAdd(1, lGeo)
# weight of the constraint
lConst.Weight = 100
lConst.Active = True
lConst.Lock = True
renameConstraint(lConst)
createConstraint()from pyfbsdk import *
def GetSelectedModels():
lModels = FBModelList()
FBGetSelectedModels(lModels)
return lModels
def CreateMarker(name='Marker', color=FBColor(1, 0, 0)):
marker = FBModelMarker(name)
marker.Show = True
marker.Look = FBMarkerLook.kFBMarkerLookHardCross
marker.PropertyList.Find("Size").Data = 500
marker.PropertyList.Find("Color RGB").Data = color
return marker
def Align(pModel, pAlignTo):
lAlignTransPos = FBVector3d();
lModelTransPos = FBVector3d();
lAlignRotPos = FBVector3d();
lModelRotPos = FBVector3d();
pAlignTo.GetVector(lAlignTransPos)
pModel.GetVector(lModelTransPos)
pAlignTo.GetVector(lAlignRotPos, FBModelTransformationType.kModelRotation)
pModel.GetVector(lModelRotPos, FBModelTransformationType.kModelRotation)
lModelTransPos[0] = lAlignTransPos[0]
lModelTransPos[1] = lAlignTransPos[1]
lModelTransPos[2] = lAlignTransPos[2]
lModelRotPos[0] = lAlignRotPos[0]
lModelRotPos[1] = lAlignRotPos[1]
lModelRotPos[2] = lAlignRotPos[2]
pModel.SetVector(lModelTransPos)
pModel.SetVector(lModelRotPos, FBModelTransformationType.kModelRotation)
del (lAlignRotPos, lAlignTransPos, lModelRotPos, lModelTransPos)
def Run():
models = GetSelectedModels()
if len(models) > 0:
for model in models:
color = FBColor(1, 0, 0)
if model.PropertyList.Find("Color RGB"):
color = model.Color
marker = CreateMarker(model.Name + "_Marker", color)
Align(marker, model)
del (color, marker)
else:
CreateMarker()
Run()
from pyfbsdk import *
import pythonidelib
from RS.Tools.FirstPersonController import Core as fpsCore
from RS import Globals
from RS.Utils import Scene
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
def activateCamConstraint():
# -- Get the namespace of the current character
charNSpace = Scene.Component.GetNamespace(FBApplication().CurrentCharacter)
# -- Create empty variables to be filled
camConstraint = None
constraintFound = False
charConstraints = []
# -- For each constraint in the scene, check if it matches the character's namespace
for con in FBSystem().Scene.Constraints:
if Scene.Component.GetNamespace(con) == charNSpace:
charConstraints.append(con)
# -- Go through each constraint that matched the character namespace and find the FPS_Cam_Constraint
for con in charConstraints:
if 'FPS_Cam_Constraint'.lower() in con.Name.lower():
camConstraint = con
# -- If we found the FPS_Cam_Constraint, activate it
if camConstraint:
constraintFound = True
camConstraint.Active = True
# -- If we didn't, let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No FPS Constraint found for current character. ",
"Continue")
del (charNSpace, camConstraint, charConstraints)
return constraintFound
def activateCHConstraints(activate):
# -- Find the cone master
coneM = findNode("coneMaster")
# -- Create an empty list to fill with the constraint channels
chConstraints = []
# -- If we found the cone master
if coneM:
# -- For For each property of the cone master
# -- If it is one of the CH drivers
# -- Add it to our list
for prop in coneM.PropertyList:
if prop.Name == "activate_L_constraint":
chConstraints.append(prop)
if prop.Name == "activate_R_constraint":
chConstraints.append(prop)
# -- If both channels are found
if len(chConstraints) == 2:
# -- Switch them on/off depending on how the function was called
for constraint in chConstraints:
constraint.Data = activate
del (coneM, chConstraints)
return True
# -- If we didn't, let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No coneMaster found for current character.",
"Continue")
del (coneM, chConstraints)
return False
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def plotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = False
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def plotSelected():
opt = plotOptions()
FBSystem().CurrentTake.PlotTakeOnSelected(opt)
def initializeCH():
# -- Check for animation nodes. If we find them, display an error message
if keyedChannelCheck():
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n Please remove any keys from 'activate_L_constraint' and ''activate_R_constraint' on the coneMaster ",
"Continue")
else:
# -- Check to see if story mode is on
isStoryMuted = FBStory().Mute
# -- Then make sure its not muted and mute all the other tracks
FBStory().Mute = False
muteOtherCharTracks()
# -- Then make sure its muted
FBStory().Mute = True
# -- Find the FPS_Cam and CH bones for the current character
fpCam = findNode("FPS_Cam")
chBones = [findNode("CH_L_Hand"), findNode("CH_R_Hand")]
constraintFound = None
coneMFound = None
# -- If both ch bones are found
if chBones[0] and chBones[1]:
# -- And the first person camera is found
if fpCam:
# -- Switch on the cam constraint
constraintFound = activateCamConstraint()
# -- If the cam constraint was found
if constraintFound:
# --Switch on the CH Driver constraints
coneMFound = activateCHConstraints(True)
# -- If the cone master was found
if coneMFound:
# --Plot the CH bones to the selected takes
for comp in FBSystem().Scene.Components:
comp.Selected = False
for bone in chBones:
bone.Selected = True
plotSelected()
for bone in chBones:
bone.Selected = False
# --Switch off the CH Driver constraints
activateCHConstraints(False)
# -- If no ch bones were found let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No CH DOFs found for current character. ",
"Continue")
# -- Set story mode back to how it was
FBStory().Mute = isStoryMuted
del (fpCam, chBones, isStoryMuted, constraintFound, coneMFound)
def keyedChannelCheck():
# -- Find the cone master
coneM = findNode("coneMaster")
# -- Create an empty list to be filled with animation nodes
animNodes = []
if coneM:
# -- For each CH driver, see if it has an animation node. If so, add it to the list.
for prop in coneM.PropertyList:
if prop.Name == "activate_L_constraint":
animNodes.append(prop.GetAnimationNode())
if prop.Name == "activate_R_constraint":
animNodes.append(prop.GetAnimationNode())
# -- If any animation nodes ar found return true
if any(animNodes):
return True
# -- otherwise false
else:
return False
def ch_to_story():
chBones = [findNode("CH_L_Hand"), findNode("CH_R_Hand")]
# -- Create a story track and clip for the current character
track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackAnimation, FBStory().RootFolder)
track.ChangeDetailsBegin()
for bone in chBones:
track.Details.append(bone)
track.ChangeDetailsEnd()
track.Label = FBSystem().CurrentTake.Name
clip = track.CopyTakeIntoTrack(FBSystem().CurrentTake.LocalTimeSpan, FBSystem().CurrentTake)
return track
def muteOtherCharTracks():
tracks = []
for lTrack in FBStory().RootFolder.Tracks:
lTrack.Mute = True
print lTrack.Name + " MUTED"
print lTrack.Mute
tracks.append(lTrack)
return tracks
def transfer():
FBSystem().Scene.Evaluate()
take = FBSystem().CurrentTake
chBones = [findNode("CH_L_Hand"), findNode("CH_R_Hand")]
if take.Name.endswith("_FirstPersonPreview"):
source_take_name = take.Name.rpartition("_")[0]
source_take = None
# switch to non preview take
for t in FBSystem().Scene.Takes:
if t.Name == source_take_name:
source_take = t
if source_take:
dup_take = take.CopyTake("TEMP_" + take.Name)
FBSystem().Scene.Evaluate()
initializeCH()
# add to story
isStoryMuted = FBStory().Mute
track = ch_to_story()
FBStory().Mute = False
FBSystem().CurrentTake = source_take
FBSystem().Scene.Evaluate()
for comp in FBSystem().Scene.Components:
comp.Selected = False
for bone in chBones:
bone.Selected = True
plotSelected()
for bone in chBones:
bone.Selected = False
# delete story and delete dup take
dup_take.FBDelete()
track.FBDelete()
FBStory().Mute = isStoryMuted
FBSystem().CurrentTake = take
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No source take found for: " + take.Name,
"Continue")
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n" + take.Name + " is not a First Person Preview Take.",
"Continue")
def run():
# -- If more than 1 take is selected,
if getNumberOfSelectedTakes() > 1:
selected_takes = []
# -- go through each take
for take in FBSystem().Scene.Takes:
# -- If it is selected
if take.Selected:
selected_takes.append(take)
for take in selected_takes:
# -- Plot selected models to it
FBSystem().CurrentTake = take
transfer()
else:
transfer()
run()
pythonidelib.FlushOutput()
# For each selected take
# Duplicate it
# Initialize the CH bones on it
# Add the CH bones to story mode
# Go to the "non preview" take and plot the ch bones
# Delete the duplicate take
from pyfbsdk import *
def closest(list, Number):
aux = []
for valor in list:
aux.append(abs(Number - valor))
return aux.index(min(aux))
def ListMarkedTakes():
lSystem = FBSystem()
markedTakes = []
for lTakeIdx in range(len(lSystem.Scene.Takes)):
if lSystem.Scene.Takes[lTakeIdx].Name.startswith('>>>---'):
markedTakes.append(lTakeIdx)
return markedTakes
def NextMarkedTake():
lSystem = FBSystem()
lCurrentTakeName = lSystem.CurrentTake.Name
markedTakes = ListMarkedTakes()
# Look in the list until we find the index of the current take.
if len(markedTakes) > 0:
for lTakeIdx in range(len(lSystem.Scene.Takes)):
if lSystem.Scene.Takes[lTakeIdx].Name == lCurrentTakeName:
if lTakeIdx in markedTakes:
lMarkedIdx = markedTakes.index(lTakeIdx)
else:
lMarkedIdx = closest(markedTakes, lTakeIdx)
break;
# Increment the index to point to the next take.
lMarkedIdx = lMarkedIdx + 1
# Wrap around the end if the current take is the last.
if lMarkedIdx == len(markedTakes): lMarkedIdx = 0
# Set the current take using our new index.
lSystem.CurrentTake = lSystem.Scene.Takes[markedTakes[lMarkedIdx]]
# Cleanup of local variables.
del lMarkedIdx
del (lSystem, lCurrentTakeName, markedTakes)
NextMarkedTake()
################################################
# -- Lifted from Animal Tools created by Mangesh
################################################
from pyfbsdk import *
def NextTake():
lSystem = FBSystem()
lCurrentTakeName = lSystem.CurrentTake.Name
# Look in the list until we find the index of the current take.
for lTakeIdx in range( len( lSystem.Scene.Takes )):
if lSystem.Scene.Takes[lTakeIdx].Name == lCurrentTakeName:
break;
# Increment the index to point to the next take.
lTakeIdx = lTakeIdx + 1
# Wrap around the end if the current take is the last.
if lTakeIdx == len( lSystem.Scene.Takes ): lTakeIdx = 0
# Set the current take using our new index.
lSystem.CurrentTake = lSystem.Scene.Takes[lTakeIdx]
# Cleanup of local variables.
del( lSystem, lCurrentTakeName, lTakeIdx )
NextTake()
from pyfbsdk import *
def closest(list, Number):
aux = []
for valor in list:
aux.append(abs(Number - valor))
return aux.index(min(aux))
def ListMarkedTakes():
lSystem = FBSystem()
markedTakes = []
for lTakeIdx in range(len(lSystem.Scene.Takes)):
if lSystem.Scene.Takes[lTakeIdx].Name.startswith('>>>---'):
markedTakes.append(lTakeIdx)
return markedTakes
def PrevMarkedTake():
lSystem = FBSystem()
lCurrentTakeName = lSystem.CurrentTake.Name
markedTakes = ListMarkedTakes()
if len(markedTakes) > 0:
# Look in the list until we find the index of the current take.
for lTakeIdx in range(len(lSystem.Scene.Takes)):
if lSystem.Scene.Takes[lTakeIdx].Name == lCurrentTakeName:
if lTakeIdx in markedTakes:
lMarkedIdx = markedTakes.index(lTakeIdx)
else:
lMarkedIdx = closest(markedTakes, lTakeIdx)
break;
# Decrement the index to point to the next take.
# Here we take advantage of Python's subscripting access
# where -1 points to the last object in the list, which is
# where we want to be if the current take is the first in
# the list.
lMarkedIdx = lMarkedIdx - 1
# Set the current take using our new index.
lSystem.CurrentTake = lSystem.Scene.Takes[markedTakes[lMarkedIdx]]
# Cleanup of local variables.
del lMarkedIdx
del (lSystem, lCurrentTakeName, markedTakes)
PrevMarkedTake()
################################################
# -- Lifted from Animal Tools created by Mangesh
################################################
from pyfbsdk import *
def PrevTake():
lSystem = FBSystem()
lCurrentTakeName = lSystem.CurrentTake.Name
# Look in the list until we find the index of the current take.
for lTakeIdx in range( len( lSystem.Scene.Takes )):
if lSystem.Scene.Takes[lTakeIdx].Name == lCurrentTakeName:
break;
# Decrement the index to point to the next take.
# Here we take advantage of Python's subscripting access
# where -1 points to the last object in the list, which is
# where we want to be if the current take is the first in
# the list.
lTakeIdx = lTakeIdx - 1
# Set the current take using our new index.
lSystem.CurrentTake = lSystem.Scene.Takes[lTakeIdx]
# Cleanup of local variables.
del( lSystem, lCurrentTakeName, lTakeIdx )
PrevTake()
from pyfbsdk import *
from pyfbsdk_additions import *
import pythonidelib
from RS.Utils import Scene
from RS import Globals
from RS.Utils import Namespace, Creation
####################################################################
# Utility Functions
####################################################################
def PlotOptions(allTakes=False):
# -- Default Options for plotting
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = allTakes
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def PlotModelList(listOfModels, allTakes=False):
# -- Take a list of models and plot them
Scene.DeSelectAll()
for model in listOfModels:
model.Selected = True
FBSystem().CurrentTake.PlotTakeOnSelected(PlotOptions(allTakes))
Scene.DeSelectAll()
def GetCharacterHeirarchyList(character):
# -- Find all nodes for the current chatacyer
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def CreateMarker(name='Marker', look='HardCross', size=500, color=FBColor(1, 0, 0)):
# -- Quick function for creating markers
marker = FBModelMarker(name)
looksDict = {
"Cube": FBMarkerLook.kFBMarkerLookCube,
"HardCross": FBMarkerLook.kFBMarkerLookHardCross,
"LightCross": FBMarkerLook.kFBMarkerLookLightCross,
"Sphere": FBMarkerLook.kFBMarkerLookSphere,
"Capsule": FBMarkerLook.kFBMarkerLookCapsule,
"Stick": FBMarkerLook.kFBMarkerLookStick,
"Bone": FBMarkerLook.kFBMarkerLookBone,
"None": FBMarkerLook.kFBMarkerLookNone
}
if look in looksDict.keys():
lookEnum = looksDict.get(look)
else:
lookEnum = FBMarkerLook.kFBMarkerLookHardCross
marker.Show = True
marker.Look = lookEnum
marker.PropertyList.Find("Size").Data = size
marker.PropertyList.Find("Color RGB").Data = color
return marker
def SwapConstraint(constraint):
# -- Take a constraint and switch the 'Source' and 'objects
child = constraint.ReferenceGet(0, 0)
parent = constraint.ReferenceGet(1, 0)
constraint.Active = False
constraint.Lock = False
constraint.ReferenceRemove(0, child)
constraint.ReferenceRemove(1, parent)
Globals.Scene.Evaluate()
constraint.ReferenceAdd(0, parent)
constraint.ReferenceAdd(1, child)
constraint.Snap()
constraint.Lock = True
Globals.Scene.Evaluate()
####################################################################
# UI Functions
####################################################################
def PopulateTool(t):
# -- Create a region for the main button
x = FBAddRegionParam(5, FBAttachType.kFBAttachTop, "")
y = FBAddRegionParam(5, FBAttachType.kFBAttachNone, "")
w = FBAddRegionParam(240, FBAttachType.kFBAttachNone, "")
h = FBAddRegionParam(30, FBAttachType.kFBAttachNone, "")
t.AddRegion("main_button_region", "main_button_region", x, y, w, h)
# -- Create the main button
t.create_button = FBButton()
t.SetControl("main_button_region", t.create_button)
t.create_button.Visible = True
t.create_button.ReadOnly = False
t.create_button.Enabled = True
t.create_button.Hint = ""
t.create_button.Caption = "Create Camera Space Setup"
t.create_button.State = 0
t.create_button.Style = FBButtonStyle.kFBPushButton
t.create_button.Justify = FBTextJustify.kFBTextJustifyCenter
t.create_button.Look = FBButtonLook.kFBLookNormal
t.create_button.OnClick.Add(MainButtonCallback)
# -- Set a bool to check if the setup has been created yet
t.created = False
ShowTool(t)
def AddDeleteButton(t):
# -- Add a second button the the UI
# -- Create a region for the delete button
x = FBAddRegionParam(5, FBAttachType.kFBAttachBottom, "")
y = FBAddRegionParam(40, FBAttachType.kFBAttachNone, "")
w = FBAddRegionParam(240, FBAttachType.kFBAttachNone, "")
h = FBAddRegionParam(30, FBAttachType.kFBAttachNone, "")
t.AddRegion("delete_button_region", "delete_button_region", x, y, w, h)
# -- Create the delete button
t.delete_button = FBButton()
t.SetControl("delete_button_region", t.delete_button)
t.delete_button.Visible = True
t.delete_button.ReadOnly = False
t.delete_button.Enabled = True
t.delete_button.Hint = ""
t.delete_button.Caption = "Delete Camera Space Setup"
t.delete_button.State = 0
t.delete_button.Style = FBButtonStyle.kFBPushButton
t.delete_button.Justify = FBTextJustify.kFBTextJustifyCenter
t.delete_button.Look = FBButtonLook.kFBLookNormal
t.delete_button.OnClick.Add(DeleteSetup)
def CloseCallback(control, event):
# -- Close the UI
CloseTool(t)
def CreateTool():
# -- Create the UI
global t
t = FBCreateUniqueTool("Hands To First Person Space")
x = 250
y = 40
t.StartSizeX = x
t.MinSizeX = x
t.MaxSizeX = x
t.StartSizeY = y
t.MinSizeY = y
t.MaxSizeY = y
PopulateTool(t)
####################################################################
# Setup Functions
####################################################################
def MainButtonCallback(control, event):
# -- Check to see if our setup has already been created
if t.created == False:
# -- If it hasn't, create one
CreateSetup()
else:
# -- If it has, plot and delete
PlotAndDeleteSetup()
def CreateSetup():
# -- Find the current character
character = FBApplication().CurrentCharacter
# -- If a character is found
if character:
# -- Check to see if the character has a control rig
if character.GetCurrentControlSet() == None:
# -- If it doesn't, create one and plot from skeleton
character.CreateControlRig(True)
character.Active = False
currentTake = FBSystem().CurrentTake
for take_index in range(len(FBSystem().Scene.Takes)):
# go to take
FBSystem().CurrentTake = FBSystem().Scene.Takes[take_index]
character.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, PlotOptions())
FBSystem().CurrentTake = currentTake
# -- Set the character's source to "Control Rig"
character.Active = True
# -- Get all the character's nodes
characterNodes = GetCharacterHeirarchyList(character)
# -- Create an empty variable to be changed if we find a camera
fpCam = None
# -- Search through all the character's nodes for the first person camera
for node in characterNodes:
if node.Name == "FPS_Cam":
# -- If it is found, change the empty variable
fpCam = node
# -- If a FPS camera was found
if fpCam:
# -- FInd the characters wrist effects
lWrist = character.GetEffectorModel(FBEffectorId.kFBLeftWristEffectorId)
rWrist = character.GetEffectorModel(FBEffectorId.kFBRightWristEffectorId)
# -- Set the wrist IK to 100 on both wrists
lWrist.PropertyList.Find("IK Reach Translation").Data = 100
lWrist.PropertyList.Find("IK Reach Rotation").Data = 100
rWrist.PropertyList.Find("IK Reach Translation").Data = 100
rWrist.PropertyList.Find("IK Reach Rotation").Data = 100
# -- Create a custom marker for our root
camParent = CreateMarker("Root", 'Bone', 50, FBColor(0.0, 0.9, 1.0))
camParent.ProcessObjectNamespace(FBNamespaceAction.kFBConcatNamespace, "FPSpace")
camParent.PropertyList.Find("Enable Transformation").Data = 0
camParent.PropertyList.Find("Enable Selection").Data = 0
# -- Create two markers for our custom hand controls
lHandMarker = CreateMarker("Ctrl_LeftHand", 'Bone', 550, FBColor(0.0, 0.9, 1.0))
lHandMarker.ProcessObjectNamespace(FBNamespaceAction.kFBConcatNamespace, "FPSpace")
rHandMarker = CreateMarker("Ctrl_RightHand", 'Bone', 550, FBColor(0.0, 0.9, 1.0))
rHandMarker.ProcessObjectNamespace(FBNamespaceAction.kFBConcatNamespace, "FPSpace")
# -- Parent the hand controls to the root
lHandMarker.Parent = camParent
rHandMarker.Parent = camParent
# -- Create a new constraint folder
constraintFolder = Creation.rs_CreateFolder("Constraints", "FBConstraint")
constraintFolder.ProcessObjectNamespace(FBNamespaceAction.kFBConcatNamespace, "FPSpace")
# -- zero constrain the parent marker to the align point. Add a namespace
rootCon = Scene.Constraint.Constraint(
Scene.Constraint.PARENT_CHILD,
"FPS_Cam > Root",
camParent,
fpCam,
Active=True,
Lock=True
)
# -- Add the constraint to the constraint folder and add a namespace
constraintFolder.Items.append(rootCon)
rootCon.ProcessObjectNamespace(FBNamespaceAction.kFBConcatNamespace, "FPSpace")
# -- zero constrain the left hand marker to the left hand. Add a namespace
lHandCon = Scene.Constraint.Constraint(
Scene.Constraint.PARENT_CHILD,
"Ctrl_LeftHand > LeftWristEffector",
lHandMarker,
lWrist,
Active=True,
Lock=True
)
# -- Add the constraint to the constraint folder and add a namespace
constraintFolder.Items.append(lHandCon)
lHandCon.ProcessObjectNamespace(FBNamespaceAction.kFBConcatNamespace, "FPSpace")
# -- zero constrain the left hand marker to the left hand. Add a namespace
rHandCon = Scene.Constraint.Constraint(
Scene.Constraint.PARENT_CHILD,
"Ctrl_RightHand > RightWristEffector",
rHandMarker,
rWrist,
Active=True,
Lock=True
)
# -- Add the constraint to the constraint folder and add a namespace
constraintFolder.Items.append(rHandCon)
rHandCon.ProcessObjectNamespace(FBNamespaceAction.kFBConcatNamespace, "FPSpace")
Globals.Scene.Evaluate()
# -- Plot the custom hand controls and flip the constraints
PlotModelList([lHandMarker, rHandMarker], allTakes=True)
Globals.Scene.Evaluate()
SwapConstraint(lHandCon)
SwapConstraint(rHandCon)
# -- Change the main button's caption
t.create_button.Caption = "Plot and Delete Camera Space Setup"
# -- Set a bool to check if the setup has been created yet
t.created = True
t.create_button.OnClick.Add(PlotAndDeleteSetup)
# -- Run function that adds a new button
AddDeleteButton(t)
# -- Add some length to the UI to make room for the new button
y = 75
t.MinSizeY = y
t.MaxSizeY = y
def PlotAndDeleteSetup(control=None, event=None):
# -- Find the current Character
character = FBApplication().CurrentCharacter
# -- If a character was found
if character:
# -- Find the character's wrist effectors
lWrist = character.GetEffectorModel(FBEffectorId.kFBLeftWristEffectorId)
rWrist = character.GetEffectorModel(FBEffectorId.kFBRightWristEffectorId)
# -- If both wrists were found
if lWrist and rWrist:
# -- Plot them on all takes
PlotModelList([lWrist, rWrist], allTakes=True)
# -- Delete the entire setup
Globals.Scene.Evaluate()
DeleteSetup()
def DeleteSetup(control=None, event=None):
# -- We gave all of objects and constraints in the setup a namespace
# -- Get this namespace
nameSpace = Namespace.GetFBNamespace("FPSpace")
if nameSpace:
# -- Delete all of the namespace's contents
for item in Namespace.GetContents(nameSpace):
item.FBDelete()
Globals.Scene.Evaluate()
# -- Delete the namespace
nameSpace.FBDelete()
del (nameSpace)
# -- Close the UI
CloseCallback(None, None)
CreateTool()
from pyfbsdk import *
import pythonidelib
from RS import Globals
from RS.Utils.Scene import Component, Groups, GetParent, GetChildren
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = GetParent(hips)
GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
# -- Make a lest of meshes to add to group
hideMeshes = [
findNode('player_zero_head_000'),
findNode('player_zero_eyes_000'),
findNode('player_zero_eyebrows_000'),
findNode('player_zero_teeth_000'),
]
groupnames = []
for group in Globals.Groups:
groupnames.append(group.Name)
# -- If any animation nodes ar found return true
if "HeadMeshes" in groupnames:
for group in Globals.Groups:
if group.Name == "HeadMeshes":
headGroup = group
else:
headGroup = FBGroup ("HeadMeshes")
# -- If those meshes were found, select them them
for mesh in hideMeshes:
if mesh:
# Adding the objects to the group
headGroup.ConnectSrc(mesh)
headGroup.Pickable = False
if headGroup.Show == True:
headGroup.Show = False
else:
headGroup.Show = Truefrom pyfbsdk import *
from RS.Utils.Scene import Component, Groups, GetParent, GetChildren
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = GetParent(hips)
GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
# -- Get the namespace of the current character
charNSpace = Component.GetNamespace(FBApplication().CurrentCharacter)
# -- Get all groups associated with this namespace
groups = Groups.GetGroupsFromNamespace(charNSpace)
# -- Switch off the werables groups
for group in groups:
if group.Name == 'Wearables_Other' \
or group.Name == 'Wearables_Outfit' \
or group.Name == 'Sliders' \
or group.Name == 'FPSCamera':
group.Show = False
if group.Name == 'Geometry':
group.Pickable = False
# -- Make a lest of meshes to hide
hideMeshes = [
findNode('player_zero_hair_000'),
findNode('player_zero_scarf_002'),
findNode('player_zero_scarf_002'),
findNode('player_zero_satchel_strap_000'),
findNode('CameraBasePivotOffset_Controller')
]
# -- If those meshes were found, hiden them
for mesh in hideMeshes:
if mesh:
mesh.Show = False####################################
# -- Quickly plot selected models --
####################################
from pyfbsdk import *
import pythonidelib
def getSelectedModels():
# -- Create an empty FBModelList
selectedModels = FBModelList()
topModel = None # -- Search all models, not just a particular branch
selectionState = True # -- Return models that are selected, not deselected
sortBySelectOrder = True # -- The last model in the list was selected most recently
FBGetSelectedModels(selectedModels, topModel, selectionState, sortBySelectOrder)
return selectedModels
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def holdFirstFrame():
# -- Create an empty list to be filled with nodes that have curves
nodesWithCurves = []
# -- Create an empty dictionary for storing keyframe times
keyTimes = {}
# -- Create an empty list of frame times
keyFrames = []
# -- For each model selected
for model in getSelectedModels():
# -- Find its properties
for lProp in model.PropertyList:
# -- For each property, find if it is animated
if lProp and lProp.IsAnimatable() and lProp.IsAnimated():
# ======== Finding Nodes capable of having FCurves =======
# -- If so, get the connected animation node
animNode = lProp.GetAnimationNode()
# -- Find all children nodes of the connected animation node
nodes = animNode.Nodes
# -- If children nodes are found
if len(nodes) > 0:
# -- Add each one to our list
for node in nodes:
nodesWithCurves.append(node)
# -- Otherwise add the anim node to our list
else:
nodesWithCurves.append(animNode)
# ======== Finding Selected Keyframes ==========
# -- For every node in our list
for node in nodesWithCurves:
# -- reset the selected key times dictionary
curveKeys = node.FCurve.Keys
keyTimes = {}
# -- If the node has an FCurve
if node.FCurve:
# -- For each keyframe on the FCurve
for key in curveKeys:
print key
pythonidelib.FlushOutput()
# -- Add the keyframe's time to the dictionary
keyTimes[key.Time.GetFrame()] = key.Time
# -- Fill the list with the frame data from the dictionary
for key in keyTimes:
print key
pythonidelib.FlushOutput()
keyFrames.append(key)
# -- Find the lowest number in the frame list. This will be our starting frame
firstKey = min(keyFrames)
secondKeyTime = FBTime(0, 0, 0, firstKey+1)
lastKey = max(keyFrames)
lastKeyTime = FBTime(0, 0, 0, lastKey)
print firstKey
print lastKey
pythonidelib.FlushOutput()
node.FCurve.KeyDeleteByTimeRange(secondKeyTime, lastKeyTime)
# -- Cleanup
del (nodesWithCurves, keyTimes, keyFrames)
def Run():
# -- If at least one model is selected
if len(getSelectedModels()) > 0:
# -- If more than 1 take is selected,
if getNumberOfSelectedTakes() > 1:
# -- go through each take
for take in FBSystem().Scene.Takes:
# -- If it is selected
if take.Selected == True:
# -- Plot selected models to it
FBSystem().CurrentTake = take
holdFirstFrame()
# -- annoying when you have one take selected different from the current - chances are the user didn't mean to.
else:
# -- Plot selected to current taKE
holdFirstFrame()
print "Plotting Complete"
else:
print "No Objects selected"
Run()
from pyfbsdk import *
from pyfbsdk_additions import *
import pythonidelib
# -- For each constraint in the scene
for con in FBSystem().Scene.Constraints:
# -- For each constraint that is selected
if con.Selected == True:
# -- Set the weight channel as animated
con.Weight.SetAnimated(True)
# -- Apply the animation node and curve to variable
weightNode = con.Weight.GetAnimationNode()
weightCurve = weightNode.FCurve
# -- Create a key with value 0 at the current frame
key = weightCurve.KeyAdd(FBSystem().LocalTime, 0)
# -- Assign the key to a variable
weightKey = weightCurve.Keys[key]
# -- Set the key to Auto and Clamped
weightKey.TangentMode = FBTangentMode(2)
weightKey.TangentClampMode = FBTangentClampMode(1)
pythonidelib.FlushOutput()
from pyfbsdk import *
from pyfbsdk_additions import *
import pythonidelib
# -- For each constraint in the scene
for con in FBSystem().Scene.Constraints:
# -- For each constraint that is selected
if con.Selected == True:
# -- Set the weight channel as animated
con.Weight.SetAnimated(True)
# -- Apply the animation node and curve to variable
weightNode = con.Weight.GetAnimationNode()
weightCurve = weightNode.FCurve
# -- Create a key with value 100 at the current frame
key = weightCurve.KeyAdd(FBSystem().LocalTime, 100)
# -- Assign the key to a variable
weightKey = weightCurve.Keys[key]
# -- Set the key to Auto and Clamped
weightKey.TangentMode = FBTangentMode(2)
weightKey.TangentClampMode = FBTangentClampMode(1)
pythonidelib.FlushOutput()
from pyfbsdk import *
from pyfbsdk_additions import *
def getSelectedModels():
# -- Create an empty FBModelList
selectedModels = FBModelList()
topModel = None # -- Search all models, not just a particular branch
selectionState = True # -- Return models that are selected, not deselected
sortBySelectOrder = True # -- The last model in the list was selected most recently
FBGetSelectedModels(selectedModels, topModel, selectionState, sortBySelectOrder)
return selectedModels
def keySelectedIKOn(selected):
for model in selected:
ik_T = model.PropertyList.Find('IK Reach Translation')
ik_R = model.PropertyList.Find('IK Reach Rotation')
IKChannels = [ik_T, ik_R]
for channel in IKChannels:
if channel:
# -- Set the channel as animated
channel.SetAnimated(True)
# -- Apply the animation node and curve to variable
channelNode = channel.GetAnimationNode()
channelCurve = channelNode.FCurve
# -- Create a key with value 100 at the current frame
key = channelCurve.KeyAdd(FBSystem().LocalTime, 0)
# -- Assign the key to a variable
channelKey = channelCurve.Keys[key]
# -- Set the key to Auto and Clamped
channelKey.TangentMode = FBTangentMode(2)
channelKey.TangentClampMode = FBTangentClampMode(1)
keySelectedIKOn(getSelectedModels())
from pyfbsdk import *
from pyfbsdk_additions import *
def getSelectedModels():
# -- Create an empty FBModelList
selectedModels = FBModelList()
topModel = None # -- Search all models, not just a particular branch
selectionState = True # -- Return models that are selected, not deselected
sortBySelectOrder = True # -- The last model in the list was selected most recently
FBGetSelectedModels(selectedModels, topModel, selectionState, sortBySelectOrder)
return selectedModels
def keySelectedIKOn(selected):
for model in selected:
ik_T = model.PropertyList.Find('IK Reach Translation')
ik_R = model.PropertyList.Find('IK Reach Rotation')
IKChannels = [ik_T, ik_R]
for channel in IKChannels:
if channel:
# -- Set the channel as animated
channel.SetAnimated(True)
# -- Apply the animation node and curve to variable
channelNode = channel.GetAnimationNode()
channelCurve = channelNode.FCurve
# -- Create a key with value 100 at the current frame
key = channelCurve.KeyAdd(FBSystem().LocalTime, 100)
# -- Assign the key to a variable
channelKey = channelCurve.Keys[key]
# -- Set the key to Auto and Clamped
channelKey.TangentMode = FBTangentMode(2)
channelKey.TangentClampMode = FBTangentClampMode(1)
keySelectedIKOn(getSelectedModels())
from pyfbsdk import *
takes = FBSystem().Scene.Takes
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
if getNumberOfSelectedTakes() > 0:
for take in takes:
if take.Selected:
newName = '>>>---' + take.Name
take.Name = newName
else:
newName = '>>>---' + FBSystem().CurrentTake.Name
FBSystem().CurrentTake.Name = newName
####################################################
# Uses story mode to move the current take to zero
####################################################
from pyfbsdk import *
import pythonidelib
# =================== Taken from Mike's mj_QuickPlot script ========================
def plotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = False
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def plotToRig(character):
character.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, plotOptions())
def plotToSkeleton(character):
character.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton, plotOptions())
# =====================================================================================
def muteOtherCharTracks():
currChar = FBApplication().CurrentCharacter
charTracks = []
for lTrack in FBStory().RootFolder.Tracks:
lChar = lTrack.PropertyList.Find('Character')
if lChar is not None:
for d in lTrack.Details:
if d == currChar:
if lTrack.Mute == False:
lTrack.Mute = True
charTracks.append(lTrack)
print "Story Track: %s temporarily muted" % lTrack.Name
return charTracks
def enableMutedTracks(charTracks):
for lTrack in charTracks:
lTrack.Mute = False
print "Story Track: %s unmuted" % lTrack.Name
def zeroStoryAndPlot(to_skeleton = True):
# -- Assign important stuff to variables
app = FBApplication()
system = FBSystem()
story = FBStory()
take = system.CurrentTake
char = FBApplication().CurrentCharacter
# -- Create a story track and clip for the current character
track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackCharacter, story.RootFolder)
track.Details.append(char)
track.Label = system.CurrentTake.Name
clip = track.CopyTakeIntoTrack(system.CurrentTake.LocalTimeSpan, system.CurrentTake)
# -- Set the start of the clip to zero
clip.PropertyList.Find('Start').Data = FBTime(0)
# -- Assign the new end of the clip to a variable
end = clip.PropertyList.Find('Stop').Data
# -- Set the start and end of the current take to match the story clip
take.LocalTimeSpan = FBTimeSpan(
FBTime(0),
end
)
# -- If the character rig is active, plot it to the skeleton and plot to it back to the rig
if to_skeleton == True:
plotToSkeleton(char)
plotToRig(char)
# -- Otherwise just plot it straight to the skeleton
else:
plotToSkeleton(char)
print "%s Moved to Zero" % (take.Name)
clip.FBDelete()
track.FBDelete()
def moveTakesToZero():
# -- Get the current character
current_character = FBApplication().CurrentCharacter
# -- Need to create control rig first?
if current_character.GetCurrentControlSet() == None:
current_character.CreateControlRig(True)
# -- Check if the current character is active
if current_character.Active == True:
to_skeleton = True
else:
to_skeleton = False
# -- Get number of takes selected
number_of_selected_takes = getNumberOfSelectedTakes()
# if there is one selected take, still ignore it and use the current take
# it's a bit annoying when you have one take selected different from the current - chances are the user didn't mean to.
if number_of_selected_takes > 1:
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
# go to take
FBSystem().CurrentTake = FBSystem().Scene.Takes[take_index]
plotToSkeleton(current_character)
zeroStoryAndPlot(to_skeleton)
else:
plotToSkeleton(current_character)
zeroStoryAndPlot(to_skeleton)
def Run():
if FBMessageBox("Move Take to Zero",
"WARNING:\n This will plot the current character on all selected takes and cannot be undone.",
"Continue", "Cancel"
) == 1:
storymute = FBStory().Mute
alreadymuted = False
if storymute:
alreadymuted = True
FBStory().Mute = False
mutedTracks = muteOtherCharTracks()
moveTakesToZero()
enableMutedTracks(mutedTracks)
if alreadymuted == True:
FBStory().Mute = True
else:
print "User cancelled"
Run()
pythonidelib.FlushOutput()from pyfbsdk import *
from pyfbsdk_additions import *
import pythonidelib
# -- Create an empty list
children = []
# -- For each selected constraint in the scene, add each child to the list
for con in FBSystem().Scene.Constraints:
if con.Selected == True:
children.append(con.ReferenceGet(0))
# -- For each child in the list, set selection to true
for c in children:
c.Selected = True
print str(c.Name) + " Selected"
pythonidelib.FlushOutput()from pyfbsdk import *
from pyfbsdk_additions import *
import pythonidelib
# -- Create an empty list
parents = []
# -- For each selected constraint in the scene, add each child to the list
for con in FBSystem().Scene.Constraints:
if con.Selected == True:
parents.append(con.ReferenceGet(1))
# -- For each parent in the list, set selection to true
for p in parents:
p.Selected = True
print str(p.Name) + " Selected"
pythonidelib.FlushOutput()from pyfbsdk import *
from RS.Utils import Scene
from RS import Globals
def CreateConstraint(parent, child):
con = Scene.Constraint.Constraint(
Scene.Constraint.PARENT_CHILD,
"Constraint",
child,
parent,
Active=True,
Lock=True
)
return con
def PlotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = True
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def PlotModelList(listOfModels):
print listOfModels
Scene.DeSelectAll()
for model in listOfModels:
model.Selected = True
Globals.Scene.Evaluate()
FBSystem().CurrentTake.PlotTakeOnSelected(PlotOptions())
Scene.DeSelectAll()
def GetSelectedModels():
lModels = FBModelList()
FBGetSelectedModels(lModels)
return lModels
def CreateMarker(name='Marker', color=FBColor(1, 0, 0)):
marker = FBModelMarker(name)
marker.Show = True
marker.Look = FBMarkerLook.kFBMarkerLookHardCross
marker.PropertyList.Find("Size").Data = 500
marker.PropertyList.Find("Color RGB").Data = color
return marker
def SwapConstraint(constraint):
# -- Take a constraint and switch the 'Source' and 'objects
child = constraint.ReferenceGet(0, 0)
parent = constraint.ReferenceGet(1, 0)
constraint.Active = False
constraint.Lock = False
constraint.ReferenceRemove(0, child)
constraint.ReferenceRemove(1, parent)
Globals.Scene.Evaluate()
constraint.ReferenceAdd(0, parent)
constraint.ReferenceAdd(1, child)
constraint.Snap()
constraint.Lock = True
Globals.Scene.Evaluate()
def Run():
models = GetSelectedModels()
if len(models) > 0:
constraints = []
markers = []
for model in models:
color = FBColor(1, 0, 0)
if model.PropertyList.Find("Color RGB"):
color = model.Color
marker = CreateMarker("PinToMarker - " + model.Name, color)
markers.append(marker)
con = CreateConstraint(model, marker)
con.Name = "PinToMarker - " + model.Name
constraints.append(con)
if markers:
PlotModelList(markers)
Globals.Scene.Evaluate()
if constraints:
for con in constraints:
SwapConstraint(con)
Globals.Scene.Evaluate()
Run()
from pyfbsdk import *
from RS.Utils import Scene
from RS import Globals
def CreateConstraint(parent, child):
con = Scene.Constraint.Constraint(
Scene.Constraint.PARENT_CHILD,
"Constraint",
child,
parent,
Active=True,
Lock=True
)
return con
def PlotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = True
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def PlotModelList(listOfModels):
print listOfModels
Scene.DeSelectAll()
for model in listOfModels:
model.Selected = True
Globals.Scene.Evaluate()
FBSystem().CurrentTake.PlotTakeOnSelected(PlotOptions())
Scene.DeSelectAll()
def GetSelectedModels():
lModels = FBModelList()
FBGetSelectedModels(lModels)
return lModels
def CreateMarker(name='Marker', color=FBColor(1, 0, 0)):
marker = FBModelMarker(name)
marker.Show = True
marker.Look = FBMarkerLook.kFBMarkerLookHardCross
marker.PropertyList.Find("Size").Data = 500
marker.PropertyList.Find("Color RGB").Data = color
return marker
def Run():
models = GetSelectedModels()
if len(models) > 0:
constraints = []
markers = []
for model in models:
color = FBColor(1, 0, 0)
if model.PropertyList.Find("Color RGB"):
color = model.Color
marker = CreateMarker("PlotToMarker - " + model.Name, color)
markers.append(marker)
con = CreateConstraint(model, marker)
con.Name = "PlotToMarker - " + model.Name
constraints.append(con)
if markers:
PlotModelList(markers)
if constraints:
for constraint in constraints:
constraint.FBDelete()
Globals.Scene.Evaluate()
Run()
from pyfbsdk import *
from RS import Globals
from RS.Utils import Scene
import pythonidelib
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
def activateCamConstraint():
# -- Get the namespace of the current character
charNSpace = Scene.Component.GetNamespace(FBApplication().CurrentCharacter)
# -- Create empty variables to be filled
camConstraint = None
constraintFound = False
charConstraints = []
# -- For each constraint in the scene, check if it matches the character's namespace
for con in FBSystem().Scene.Constraints:
if Scene.Component.GetNamespace(con) == charNSpace:
charConstraints.append(con)
# -- Go through each constraint that matched the character namespace and find the FPS_Cam_Constraint
for con in charConstraints:
if 'FPS_Cam_Constraint'.lower() in con.Name.lower():
camConstraint = con
# -- If we found the FPS_Cam_Constraint, activate it
if camConstraint:
constraintFound = True
camConstraint.Active = True
# -- If we didn't, let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No FPS Constraint found for current character. ",
"Continue")
del (charNSpace, camConstraint, charConstraints)
return constraintFound
def activateCHConstraints(activate):
# -- Find the cone master
coneM = findNode("coneMaster")
# -- Create an empty list to fill with the constraint channels
chConstraints = []
# -- If we found the cone master
if coneM:
# -- For For each property of the cone master
# -- If it is one of the CH drivers
# -- Add it to our list
for prop in coneM.PropertyList:
if prop.Name == "activate_L_constraint":
chConstraints.append(prop)
if prop.Name == "activate_R_constraint":
chConstraints.append(prop)
# -- If both channels are found
if len(chConstraints) == 2:
# -- Switch them on/off depending on how the function was called
for constraint in chConstraints:
constraint.Data = activate
del (coneM, chConstraints)
return True
# -- If we didn't, let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No coneMaster found for current character.",
"Continue")
del (coneM, chConstraints)
return False
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def plotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = False
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def plotSelected(take):
opt = plotOptions()
take.PlotTakeOnSelected(opt)
def plotOnSelectedTakes(bones):
selection = []
# -- If more than 1 take is selected,
if getNumberOfSelectedTakes() > 1:
takesToPlot = []
# -- Store the takes the user has selected
for take in FBSystem().Scene.Takes:
if take.Selected == True:
takesToPlot.append(take)
# -- Store the user selection and deselect everything
for comp in FBSystem().Scene.Components:
if comp.Selected == True:
selection.append(comp)
comp.Selected = False
# -- Select the ch bones
for bone in bones:
bone.Selected = True
# -- Go through each selected take
for take in takesToPlot:
# -- Plot selected models to it
plotSelected(take)
print "CH Bones Initialized for take: " + str(take.Name)
# -- Deselect the bones
for bones in bones:
bones.Selected = False
# -- Reselect the user selection
for object in selection:
object.Selected = True
del (selection, takesToPlot)
# -- annoying when you have one take selected different from the current - chances are the user didn't mean to.
else:
# -- Store the user selection and deselect everything
for comp in FBSystem().Scene.Components:
if comp.Selected == True:
selection.append(comp)
comp.Selected = False
# -- Select the ch bones
for bone in bones:
bone.Selected = True
# -- Plot selected to current take
take = FBSystem().CurrentTake
plotSelected(take)
print "CH Bones Initialized for current take"
# -- Deselect the bones
for bones in bones:
bones.Selected = False
# -- Reselect the user selection
for object in selection:
object.Selected = True
del selection
def initializeCH():
# -- Check for animation nodes. If we find them, display an error message
if keyedChannelCheck():
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n Please remove any keys from 'activate_L_constraint' and ''activate_R_constraint' on the coneMaster ",
"Continue")
else:
# -- Check to see if story mode is on
isStoryMuted = FBStory().Mute
# -- Then make sure its off
FBStory().Mute = True
# -- Find the FPS_Cam and CH bones for the current character
fpCam = findNode("FPS_Cam")
chBones = [findNode("CH_L_Hand"), findNode("CH_R_Hand")]
constraintFound = None
coneMFound = None
# -- If both ch bones are found
if chBones[0] and chBones[1]:
# -- And the first person camera is found
if fpCam:
# -- Switch on the cam constraint
constraintFound = activateCamConstraint()
# -- If the cam constraint was found
if constraintFound:
# --Switch on the CH Driver constraints
coneMFound = activateCHConstraints(True)
# -- If the cone master was found
if coneMFound:
# --Plot the CH bones to the selected takes
plotOnSelectedTakes(chBones)
# --Switch off the CH Driver constraints
activateCHConstraints(False)
# -- If no ch bones were found let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No CH DOFs found for current character. ",
"Continue")
# -- Set story mode back to how it was
FBStory().Mute = isStoryMuted
del (fpCam, chBones, isStoryMuted, constraintFound, coneMFound)
def keyedChannelCheck():
# -- Find the cone master
coneM = findNode("coneMaster")
# -- Create an empty list to be filled with animation nodes
animNodes = []
if coneM:
# -- For each CH driver, see if it has an animation node. If so, add it to the list.
for prop in coneM.PropertyList:
if prop.Name == "activate_L_constraint":
animNodes.append(prop.GetAnimationNode())
if prop.Name == "activate_R_constraint":
animNodes.append(prop.GetAnimationNode())
# -- If any animation nodes ar found return true
if any(animNodes):
return True
# -- otherwise false
else:
return False
initializeCH()
Globals.Scene.Evaluate()
pythonidelib.FlushOutput()from pyfbsdk import *
from RS import Globals
from RS.Utils import Scene
import pythonidelib
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
def activateCamConstraint():
# -- Get the namespace of the current character
charNSpace = Scene.Component.GetNamespace(FBApplication().CurrentCharacter)
# -- Create empty variables to be filled
camConstraint = None
constraintFound = False
charConstraints = []
# -- For each constraint in the scene, check if it matches the character's namespace
for con in FBSystem().Scene.Constraints:
if Scene.Component.GetNamespace(con) == charNSpace:
charConstraints.append(con)
# -- Go through each constraint that matched the character namespace and find the FPS_Cam_Constraint
for con in charConstraints:
if 'FPS_Cam_Constraint'.lower() in con.Name.lower():
camConstraint = con
# -- If we found the FPS_Cam_Constraint, activate it
if camConstraint:
constraintFound = True
camConstraint.Active = True
# -- If we didn't, let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No FPS Constraint found for current character. ",
"Continue")
del (charNSpace, camConstraint, charConstraints)
return constraintFound
def activateCHConstraints(activate):
# -- Find the cone master
coneM = findNode("coneMaster")
# -- Create an empty list to fill with the constraint channels
chConstraints = []
# -- If the conemaster was found:
if coneM:
# -- For For each property of the cone master
# -- If it is one of the CH drivers
# -- Add it to our list
for prop in coneM.PropertyList:
if prop.Name == "activate_L_constraint":
chConstraints.append(prop)
if prop.Name == "activate_R_constraint":
chConstraints.append(prop)
# -- If both channels are found
if len(chConstraints) == 2:
# -- Switch them on/off depending on how the function was called
for constraint in chConstraints:
constraint.Data = activate
del (coneM, chConstraints)
return True
# -- If we didn't, let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No coneMaster found for current character.",
"Continue")
del (coneM, chConstraints)
return False
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def plotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = False
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def plotSelected(take):
opt = plotOptions()
take.PlotTakeOnSelected(opt)
def plotOnAllTakes(bones):
selection = []
takesToPlot = []
# -- Get every take in the scene
for take in FBSystem().Scene.Takes:
takesToPlot.append(take)
# -- Store the user selection and deselect everything
for comp in FBSystem().Scene.Components:
if comp.Selected == True:
selection.append(comp)
comp.Selected = False
# -- Select the ch bones
for bone in bones:
bone.Selected = True
# -- Go through each take
for take in takesToPlot:
# -- Plot selected models to it
plotSelected(take)
print "CH Bones Initialized for take: " + str(take.Name)
# -- Deselect the bones
for bones in bones:
bones.Selected = False
# -- Reselect the user selection
for object in selection:
object.Selected = True
del (selection, takesToPlot)
def initializeCH():
# -- Check for animation nodes. If we find them, display an error message
if keyedChannelCheck():
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n Please remove any keys from 'activate_L_constraint' and ''activate_R_constraint' on the coneMaster ",
"Continue")
else:
# -- Check to see if story mode is on
isStoryMuted = FBStory().Mute
# -- Then make sure its off
FBStory().Mute = True
# -- Find the FPS_Cam and CH bones for the current character
fpCam = findNode("FPS_Cam")
chBones = [findNode("CH_L_Hand"), findNode("CH_R_Hand")]
constraintFound = None
coneMFound = None
# -- If both ch bones are found
if chBones[0] and chBones[1]:
# -- And the first person camera is found
if fpCam:
# -- Switch on the cam constraint
constraintFound = activateCamConstraint()
# --If the cam constraint was found
if constraintFound:
# --Switch on the CH Driver constraints
coneMFound = activateCHConstraints(True)
# -- If the cne master was found
if coneMFound:
# --Plot the CH bones to the selected takes
plotOnAllTakes(chBones)
# --Switch off the CH Driver constraints
activateCHConstraints(False)
# -- If no ch bones were found let the user know
else:
FBMessageBox("Quick Initialize CH Bones",
"WARNING:\n No CH DOFs found for current character. ",
"Continue")
# -- Set story mode back to how it was
FBStory().Mute = isStoryMuted
del (fpCam, chBones, isStoryMuted, constraintFound, coneMFound)
def keyedChannelCheck():
# -- Find the cone master
coneM = findNode("coneMaster")
# -- Create an empty list to be filled with animation nodes
animNodes = []
# -- If the cone master was found
if coneM:
# -- For each CH driver, see if it has an animation node. If so, add it to the list.
for prop in coneM.PropertyList:
if prop.Name == "activate_L_constraint":
animNodes.append(prop.GetAnimationNode())
if prop.Name == "activate_R_constraint":
animNodes.append(prop.GetAnimationNode())
# -- If any animation nodes ar found return true
if any(animNodes):
return True
# -- otherwise false
else:
return False
initializeCH()
Globals.Scene.Evaluate()
pythonidelib.FlushOutput()####################################################################
# Quickly Plot either down to skeleton or vice versa depending on current state
####################################################################
from pyfbsdk import *
import RS.Globals
import RS.Core as Core
def plotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = False
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def plotToRig(character):
character.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, plotOptions())
def plotToSkeleton(character):
character.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton, plotOptions())
def ToggleDevices():
for device in FBSystem().Scene.Devices:
device.Online = not device.Online
def QuickPlot():
# ToggleDevices()
current_character = FBApplication().CurrentCharacter
# need to create control rig first?
if current_character.GetCurrentControlSet() == None:
current_character.CreateControlRig(True)
if current_character.Active == True:
to_skeleton = True
else:
to_skeleton = False
number_of_selected_takes = getNumberOfSelectedTakes()
# if there is one selected take, still ignore it and use the current take
# it's a bit annoying when you have one take selected different from the current - chances are the user didn't mean to.
if number_of_selected_takes > 1:
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
# go to take
FBSystem().CurrentTake = FBSystem().Scene.Takes[take_index]
if to_skeleton == True:
plotToSkeleton(current_character)
else:
plotToRig(current_character)
else:
if to_skeleton == True:
for character in Core.System.Scene.Characters:
plotToSkeleton(character)
else:
for character in Core.System.Scene.Characters:
plotToRig(character)
# ToggleDevices()
print "Plotting Complete"
####################################################################
# Main
####################################################################
QuickPlot()####################################
# -- Quickly plot selected models --
####################################
from pyfbsdk import *
from pyfbsdk_additions import *
def getSelectedModels():
# -- Create an empty FBModelList
selectedModels = FBModelList()
topModel = None # -- Search all models, not just a particular branch
selectionState = True # -- Return models that are selected, not deselected
sortBySelectOrder = True # -- The last model in the list was selected most recently
FBGetSelectedModels(selectedModels, topModel, selectionState, sortBySelectOrder)
return selectedModels
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def plotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = False
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def plotSelected(take):
opt = plotOptions()
take.PlotTakeOnSelected(opt)
def QuickPlot():
# -- Get selected models
sel = getSelectedModels()
# -- If at least one model is selected
if len(sel) > 0:
# -- If more than 1 take is selected,
if getNumberOfSelectedTakes() > 1:
# -- go through each take
for take in FBSystem().Scene.Takes:
# -- If it is selected
if take.Selected == True:
# -- Plot selected models to it
plotSelected(take)
print "Selected Objects plotted to " + str(take.Name)
# -- annoying when you have one take selected different from the current - chances are the user didn't mean to.
else:
# -- Plot selected to current taKE
take = FBSystem().CurrentTake
plotSelected(take)
print "Selected Objects plotted to current take"
print "Plotting Complete"
else:
print "No Objects selected"
QuickPlot()####################################################
# Uses story mode to move the current take to zero
####################################################
from pyfbsdk import *
import pythonidelib
# =================== Taken from Mike's mj_QuickPlot script ========================
def plotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = False
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def plotToRig(character):
character.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, plotOptions())
def plotToSkeleton(character):
character.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton, plotOptions())
# =====================================================================================
def muteOtherCharTracks():
currChar = FBApplication().CurrentCharacter
charTracks = []
for lTrack in FBStory().RootFolder.Tracks:
lChar = lTrack.PropertyList.Find('Character')
if lChar is not None:
for d in lTrack.Details:
if d == currChar:
if lTrack.Mute == False:
lTrack.Mute = True
charTracks.append(lTrack)
# print "Story Track: %s temporarily muted" % lTrack.Name
return charTracks
def enableMutedTracks(charTracks):
for lTrack in charTracks:
lTrack.Mute = False
# print "Story Track: %s unmuted" % lTrack.Name
def scaleStoryAndPlot(ratescale, to_skeleton = True):
# -- Assign important stuff to variables
app = FBApplication()
system = FBSystem()
story = FBStory()
take = system.CurrentTake
char = FBApplication().CurrentCharacter
# -- Create a story track and clip for the current character
track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackCharacter, story.RootFolder)
track.Details.append(char)
track.Label = system.CurrentTake.Name
clip = track.CopyTakeIntoTrack(system.CurrentTake.LocalTimeSpan, system.CurrentTake)
# -- Get some time information about the clip we created
lSpeed = clip.PropertyList.Find('Speed')
lStart = clip.PropertyList.Find('Start')
lStop = clip.PropertyList.Find('Stop')
# -- Use the start and end of the clip to determine the length
oldLength = lStop.Data.GetFrame() - lStart.Data.GetFrame()
# -- Calculate a new length based on the ratescale
fScaledLength = float(oldLength / ratescale)
# -- Convert length to an integer (and round up)
iScaledLength = int(fScaledLength)
# -- Set the speed of the clip to the desired ratescale
lSpeed.Data = ratescale
# -- Use the new length, added to the current start time, to assign a new stop time
lStop.Data = FBTime(0, 0, 0, lStart.Data.GetFrame() + iScaledLength, 0)
# -- Assign the new end of the clip to a variable
end = clip.PropertyList.Find('Stop').Data
# -- Set the start and end of the current take to match the story clip
take.LocalTimeSpan = FBTimeSpan(
lStart.Data,
end
)
# -- Add 1 frame to the end of the clip as padding
lStop.Data = FBTime(0, 0, 0, lStop.Data.GetFrame() + 1, 0)
# -- If the character rig is active, plot it to the skeleton and plot to it back to the rig
if to_skeleton == True:
plotToSkeleton(char)
plotToRig(char)
# -- Otherwise just plot it straight to the skeleton
else:
plotToSkeleton(char)
print "%s rate scaled to %s" % (take.Name, round(ratescale,1))
clip.FBDelete()
track.FBDelete()
def ratescaleTakes(ratescale):
# -- Get the current character
current_character = FBApplication().CurrentCharacter
# -- Need to create control rig first?
if current_character.GetCurrentControlSet() == None:
current_character.CreateControlRig(True)
# -- Check if the current character is active
if current_character.Active == True:
to_skeleton = True
else:
to_skeleton = False
# -- Get number of takes selected
number_of_selected_takes = getNumberOfSelectedTakes()
# if there is one selected take, still ignore it and use the current take
# it's a bit annoying when you have one take selected different from the current - chances are the user didn't mean to.
if number_of_selected_takes > 1:
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
# go to take
FBSystem().CurrentTake = FBSystem().Scene.Takes[take_index]
plotToSkeleton(current_character)
scaleStoryAndPlot(ratescale, to_skeleton)
else:
plotToSkeleton(current_character)
scaleStoryAndPlot(ratescale, to_skeleton)
def Run():
# -- Get the amount that the user wants to scale and let them confirm they want to plot all selected takes
pUpTitle = "Rate Scale Takes"
pUpMessage = """WARNING:\n This will plot the current character on all selected takes and cannot be undone.\n\nRate Scale Amount:"""
input = FBMessageBoxGetUserValue( pUpTitle,
pUpMessage,
1.0,
FBPopupInputType.kFBPopupFloat,
"Continue",
"Cancel"
)
if input[0] == 1:
storymute = FBStory().Mute
alreadymuted = False
if storymute:
alreadymuted = True
FBStory().Mute = False
mutedTracks = muteOtherCharTracks()
ratescaleTakes(input[1])
enableMutedTracks(mutedTracks)
if alreadymuted == True:
FBStory().Mute = True
else:
print "User cancelled"
Run()
pythonidelib.FlushOutput()from pyfbsdk import *
from pyfbsdk_additions import *
def renameConstraint(con):
if con.ReferenceGroupGetCount() in range(2,4):
child = con.ReferenceGet(0)
parent = con.ReferenceGet(1)
type = con.Description
if con.Description == 'Position From Positions':
type = 'Position'
elif con.Description == 'Rotation From Rotations':
type = 'Rotation'
elif con.Description == 'Scale From Scales':
type = 'Scale'
if child and parent:
newName = type + ' - ' + parent.Name + ' > ' + child.Name
con.Name = newName
else:
newName = type + ' - [EMPTY CONSTRAINT]'
con.Name = newName
# -- For each constraint in the scene
for con in FBSystem().Scene.Constraints:
# -- If the constraint is selected
if con.Selected == True:
renameConstraint(con)
from pyfbsdk import *
import pythonidelib
from RS.Tools.FirstPersonController import Core as fpsCore
from RS import Globals
from RS.Utils import Scene
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
def bakeRot():
currentCharacter = FBApplication().CurrentCharacter
# -- If more than 1 take is selected,
if getNumberOfSelectedTakes() > 1:
# -- go through each take
for take in FBSystem().Scene.Takes:
# -- If it is selected
if take.Selected:
# -- Plot selected models to it
FBSystem().CurrentTake = take
Globals.Scene.Evaluate()
startTime = FBSystem().CurrentTake.LocalTimeSpan.GetStart()
endTime = FBSystem().CurrentTake.LocalTimeSpan.GetStop()
fpsCore.TransferConeMasterAnimationToMoverSpace(currentCharacter, startTime, endTime)
Globals.Scene.Evaluate()
cleanCurves()
# -- annoying when you have one take selected different from the current - chances are the user didn't mean to.
else:
startTime = FBSystem().CurrentTake.LocalTimeSpan.GetStart()
endTime = FBSystem().CurrentTake.LocalTimeSpan.GetStop()
fpsCore.TransferConeMasterAnimationToMoverSpace(currentCharacter, startTime, endTime)
Globals.Scene.Evaluate()
def plotOptions():
plot_options = FBPlotOptions()
plot_options.PlotAllTakes = False
plot_options.PlotOnFrame = True
plot_options.PlotPeriod = FBTime(0, 0, 0, 1)
plot_options.RotationFilterToApply = FBRotationFilter.kFBRotationFilterUnroll
plot_options.UseConstantKeyReducer = False
plot_options.ConstantKeyReducerKeepOneKey = True
plot_options.PlotTranslationOnRootOnly = False
return plot_options
def plotSelected():
opt = plotOptions()
FBSystem().CurrentTake.PlotTakeOnSelected(opt)
def cleanCurves():
# -- Find the cone master
coneM = findNode("coneMaster")
for comp in FBSystem().Scene.Components:
comp.Selected = False
coneM.Selected = True
plotSelected()
bakeRot()
Globals.Scene.Evaluate()
pythonidelib.FlushOutput()
###########################################
# -- Quickly pick the IK Hand Extentions --
###########################################
from pyfbsdk import *
from pyfbsdk import *
from RS.Utils import Scene
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNodesForCurrentCharacter(name):
foundNode = None
foundNodes = []
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
foundNodes.append(foundNode)
del (currentCharacter, characterNodeList)
return foundNodes
def findNodesForEntireScene(name):
foundComponents = FBComponentList()
includeNamespace = True
modelsOnly = True
FBFindObjectsByName('*' + name, foundComponents, includeNamespace, modelsOnly)
return foundComponents
def selectNode(input, character = True):
nodes = []
names = [x.strip() for x in input.split(',')]
if character == True:
for name in names:
for node in findNodesForCurrentCharacter(name):
nodes.append(node)
else:
for name in names:
for node in findNodesForEntireScene(name):
nodes.append(node)
if len(nodes) > 0:
clearSelection()
for node in nodes:
if node:
if node.PropertyList.Find('Look'):
node.PropertyList.Find('Look').Data = 1
if node.PropertyList.Find('Size'):
node.PropertyList.Find('Size').Data = 5.0
if node.PropertyList.Find('Pickable'):
node.PropertyList.Find('Pickable').Data = True
if node.PropertyList.Find('Transformable'):
node.PropertyList.Find('Transformable').Data = True
if node.PropertyList.Find('Show'):
node.PropertyList.Find('Show').Data = True
node.Selected = True
return nodes
def TestMessageBox(pVal):
# The result from the call will be a tuple containing the index of the
# button pressed (or -1 in case of error). The second element will be
# the value entered.
lRes = FBMessageBoxGetUserValue("Search and Select", "Search For: ", pVal, FBPopupInputType.kFBPopupString, "Character", "Scene", "Cancel")
# Did the user press 'Ok'?
if lRes[0] == 1:
found = selectNode(lRes[1], True)
if len(found) > 0:
FBMessageBox("Result", "%s object found for current character" % len(found), "Ok")
else:
FBMessageBox("Result", "No objects found for current character", "Ok")
if lRes[0] == 2:
found = selectNode(lRes[1], False)
if len(found) > 0:
FBMessageBox("Result", "%s objects found in scene" % len(found), "Ok")
else:
FBMessageBox("Result", "No objects found in scene", "Ok")
del (lRes)
def clearSelection():
for comp in FBSystem().Scene.Components:
comp.Selected = False
TestMessageBox("")
###########################################
# -- Quickly pick the IK Hand Extentions --
###########################################
from pyfbsdk import *
from pyfbsdk import *
from RS.Utils import Scene
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
def selectFromList(names):
for name in names:
node = findNode(name)
if node:
node.PropertyList.Find('Look').Data = 1
node.Look = 1
node.Size = 5.0
node.Pickable = True
node.Transformable = True
node.Show = True
node.Selected = True
selectList = [
"CH_L_Hand",
"CH_R_Hand"
]
selectFromList(selectList)
###########################################
# -- Quickly pick the IK Hand Extentions --
###########################################
from pyfbsdk import *
from pyfbsdk import *
from RS.Utils import Scene
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
def selectFromList(names):
for name in names:
node = findNode(name)
if node:
node.PropertyList.Find('Look').Data = 1
node.Look = 1
node.Size = 5.0
node.Pickable = True
node.Transformable = True
node.Show = True
node.Selected = True
selectList = [
"IK_L_Hand",
"IK_R_Hand"
]
selectFromList(selectList)
###########################################
# -- Quickly pick the IK Hand Extentions --
###########################################
from pyfbsdk import *
from pyfbsdk import *
from RS.Utils import Scene
def getCharacterHeirarchyList(character):
characterNodeList = []
hips = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
dummy = Scene.GetParent(hips)
Scene.GetChildren(dummy, characterNodeList, "", True)
return characterNodeList
def findNode(name):
foundNode = None
# -- Get list of all nodes of current character
currentCharacter = FBApplication().CurrentCharacter
characterNodeList = getCharacterHeirarchyList(currentCharacter)
# -- Check each node to see if it matches the desired name
for node in characterNodeList:
if node.Name == name:
foundNode = node
del (currentCharacter, characterNodeList)
return foundNode
def selectFromList(names):
for name in names:
node = findNode(name)
if node:
node.PropertyList.Find('Look').Data = 1
node.Look = 1
node.Size = 5.0
node.Pickable = True
node.Transformable = True
node.Show = True
node.Selected = True
selectList = [
"PH_L_Hand",
"PH_R_Hand"
]
selectFromList(selectList)
from pyfbsdk import *
import pythonidelib
def SelectMarkedTakes():
lSystem = FBSystem()
print "\nMarked Takes:\n"
for lTakeIdx in range(len(lSystem.Scene.Takes)):
take = lSystem.Scene.Takes[lTakeIdx]
take.Selected = False
if take.Name.startswith('>>>---'):
take.Selected = True
print take.Name[6:]
pythonidelib.FlushOutput()
SelectMarkedTakes()
from pyfbsdk import *
from pyfbsdk_additions import *
# -- For each constraint in the scene
for con in FBSystem().Scene.Constraints:
if con.Selected == True:
newName = con.Name + ' [ANIMATED]'
con.Name = newName
####################################################################
# Adds current character as a story track with current take added
####################################################################
from pyfbsdk import *
import pythonidelib
def addCharacterTrack():
track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackCharacter, story.RootFolder)
track.Details.append(app.CurrentCharacter)
track.Label = system.CurrentTake.Name
clip = track.CopyTakeIntoTrack(system.CurrentTake.LocalTimeSpan, system.CurrentTake)
clip.Selected = True
interp = clip.PropertyList.Find('Timewarp Interpolation')
interp.Data = 0
FBStory().Mute = False
app = FBApplication()
system = FBSystem()
story = FBStory()
scene = system.Scene
addCharacterTrack()
pythonidelib.FlushOutput()
from pyfbsdk import *
takes = FBSystem().Scene.Takes
def getNumberOfSelectedTakes():
number_of_selected_takes = 0
for take_index in range(len(FBSystem().Scene.Takes)):
if FBSystem().Scene.Takes[take_index].Selected == True:
number_of_selected_takes += 1
return number_of_selected_takes
if getNumberOfSelectedTakes() > 0:
for take in takes:
if take.Selected:
if take.Name.startswith('>>>---'):
take.Name = take.Name[6:]
else:
if FBSystem().CurrentTake.Name.startswith('>>>---'):
FBSystem().CurrentTake.Name = FBSystem().CurrentTake.Name[6:]