def execute(self, operation, in_frame=None, out_frame=None, **kwargs): """ Main hook entry point :operation: String Frame operation to perform :in_frame: int in_frame for the current context (e.g. the current shot, current asset etc) :out_frame: int out_frame for the current context (e.g. the current shot, current asset etc) :returns: Depends on operation: 'set_frame_range' - Returns if the operation was succesfull 'get_frame_range' - Returns the frame range in the form (in_frame, out_frame) """ if operation == "get_frame_range": ticks = MaxPlus.Core.EvalMAXScript("ticksperframe").GetInt() current_in = MaxPlus.Animation.GetAnimRange().Start() / ticks current_out = MaxPlus.Animation.GetAnimRange().End() / ticks return (current_in, current_out) elif operation == "set_frame_range": import MaxPlus ticks = MaxPlus.Core.EvalMAXScript("ticksperframe").GetInt() range = MaxPlus.Interval(in_frame * ticks, out_frame * ticks) MaxPlus.Animation.SetRange(range) return True
def setFrameRange(self, origin, startFrame, endFrame): if startFrame == endFrame: QMessageBox.warning(self.core.messageParent, "Warning", "The startframe and the endframe cannot be the same in 3dsMax.") return MaxPlus.Animation.SetRange(MaxPlus.Interval(startFrame*MaxPlus.Animation.GetTicksPerFrame(), endFrame*MaxPlus.Animation.GetTicksPerFrame())) MaxPlus.Animation.SetTime(startFrame*MaxPlus.Animation.GetTicksPerFrame())
def LoadSEAnimMakeKeys(filepath=""): # Load a seanim file using seanim api print("Loading SEAnim file...") # Load the file using helper lib anim = SEAnim.Anim(filepath) # Starting frame start_frame = 0 # End frame end_frame = anim.header.frameCount - 1 # Set scene start and end newRange = MaxPlus.Interval((start_frame * MAX_TICKS), (end_frame * MAX_TICKS)) # Set it MaxPlus.Animation.SetRange(newRange) # Loop through bones for bone in anim.bones: # TODO: Parent modifiers BoneAnimType = anim.header.animType # Fetch this bone in the scene, if it exists BoneJoint = MaxPlus.INode.GetINodeByName(bone.name) # Check if BoneJoint is None: # Just skip it print "SEAnim -> WARN: Failed to find bone: " + bone.name # Skip continue # Reset rotation values if len(bone.rotKeys) > 0: # Reset rotation to 0, 0, 0 (SetLocalRotation(...??)) print "TODO" # Grab the bone rest transform BoneRestTransform = BoneJoint.GetLocalPosition() # Loop through position keys, if any if len(bone.posKeys) > 0: # Prepare to animate this bone MaxPlus.Animation.SetAnimateButtonState(True) # Set linear tangents (TODO: Check what values are MAX linear in / out) MaxPlus.Animation.SetDefaultTangentType(5, 5) # Loop through the keyframes for key in bone.posKeys: # Set the current scene time MaxPlus.Animation.SetTime(key.frame * MAX_TICKS) # Check animation type to see what data we need if BoneAnimType == SEAnim.SEANIM_TYPE.SEANIM_TYPE_ABSOLUTE: # Add absolute keyframe print "TODO" else: # Add relative keyframe print "TODO" # End this bone's pos keys MaxPlus.Animation.SetAnimateButtonState(False) # TODO: Notifications # Reset time back to first frame MaxPlus.Animation.SetTime((start_frame * MAX_TICKS), True) # Finished print("The animation has been loaded")
def SetAnimationRanges(): '''Changes the animation range from the default of 100 frames to 200 frames''' anim = MaxPlus.Animation PrintInterval(anim.GetAnimRange()) # Intervals come in units of ticks. Each frame is 160 ticks. newFrames = 200 * 160 newRange = MaxPlus.Interval(0, newFrames) anim.SetRange(newRange) # The animation slider now shows 200 frames PrintInterval(anim.GetAnimRange())
def SetAnimationRanges(start_frame=0, end_frame=100): '''Changes the animation range from the default of 100 frames to 200 frames''' anim = MaxPlus.Animation PrintInterval(anim.GetAnimRange()) # Intervals come in units of ticks. Each frame is 160 ticks. ticks_per_frame = 160 start_tick = start_frame * ticks_per_frame end_tick = end_frame * ticks_per_frame anim_range = MaxPlus.Interval(start_tick, end_tick) anim.SetRange(anim_range)
def set_frame_range(self, in_frame=None, out_frame=None, **kwargs): """ set_frame_range will set the frame range using `in_frame` and `out_frame` :param int in_frame: in_frame for the current context (e.g. the current shot, current asset etc) :param int out_frame: out_frame for the current context (e.g. the current shot, current asset etc) """ ticks = MaxPlus.Core.EvalMAXScript("ticksperframe").GetInt() range = MaxPlus.Interval(in_frame * ticks, out_frame * ticks) MaxPlus.Animation.SetRange(range)
def set_editorial_data(self, in_frame=None, out_frame=None, frame_rate=None, **kwargs): """ set_editorial_data will set the frame range using `in_frame` and `out_frame` and the frame rate using `frame_rate` :param int in_frame: in_frame for the current context (e.g. the current shot, current asset etc) :param int out_frame: out_frame for the current context (e.g. the current shot, current asset etc) :param float frame_rate: frame_range for the current context (e.g. the current shot, current asset, or current project) """ ticks = MaxPlus.Core.EvalMAXScript("ticksperframe").GetInt() range = MaxPlus.Interval(in_frame * ticks, out_frame * ticks) MaxPlus.Animation.SetRange(range)
def set_frame_range(self, engine, in_frame, out_frame): if engine == "tk-maya": import pymel.core as pm # set frame ranges for plackback pm.playbackOptions(minTime=in_frame, maxTime=out_frame, animationStartTime=in_frame, animationEndTime=out_frame) # set frame ranges for rendering defaultRenderGlobals = pm.PyNode('defaultRenderGlobals') defaultRenderGlobals.startFrame.set(in_frame) defaultRenderGlobals.endFrame.set(out_frame) elif engine == "tk-nuke": import nuke # unlock locked = nuke.root()["lock_range"].value() if locked: nuke.root()["lock_range"].setValue(False) # set values nuke.root()["first_frame"].setValue(in_frame) nuke.root()["last_frame"].setValue(out_frame) # and lock again if locked: nuke.root()["lock_range"].setValue(True) elif engine == "tk-motionbuilder": from pyfbsdk import FBPlayerControl, FBTime lPlayer = FBPlayerControl() lPlayer.LoopStart = FBTime(0, 0, 0, in_frame) lPlayer.LoopStop = FBTime(0, 0, 0, out_frame) elif engine == "tk-softimage": import win32com Application = win32com.client.Dispatch('XSI.Application') # set playback control Application.SetValue("PlayControl.In", in_frame) Application.SetValue("PlayControl.Out", out_frame) Application.SetValue("PlayControl.GlobalIn", in_frame) Application.SetValue("PlayControl.GlobalOut", out_frame) # set frame ranges for rendering Application.SetValue("Passes.RenderOptions.FrameStart", in_frame) Application.SetValue("Passes.RenderOptions.FrameEnd", out_frame) elif engine == "tk-houdini": import hou # We have to use hscript until SideFX gets around to implementing hou.setGlobalFrameRange() hou.hscript("tset `((%s-1)/$FPS)` `(%s/$FPS)`" % (in_frame, out_frame)) hou.playbar.setPlaybackRange(in_frame, out_frame) elif engine == "tk-3dsmax": from Py3dsMax import mxs mxs.animationRange = mxs.interval(in_frame, out_frame) elif engine == "tk-3dsmaxplus": import MaxPlus ticks = MaxPlus.Core.EvalMAXScript("ticksperframe").GetInt() range = MaxPlus.Interval(in_frame * ticks, out_frame * ticks) MaxPlus.Animation.SetRange(range) else: raise tank.TankError( "Don't know how to set current frame range for engine %s!" % engine)