โจ๐ฌ ๐๐๐ฌ ๐๐ค๐ค๐ก ๐๐ฃ๐ฉ๐ง๐ค: "๐๐๐ฎ๐๐ง๐๐ข๐๐ฃ๐จ๐ฉ๐ง๐๐๐จ๐๐ง๐๐ง๐ค" ๐๏ธโจ
Hello VFX & Animation Professionals! ๐
I'm thrilled to introduce an essential addition to your Maya toolkitโKeyframeCleanerPro! ๐
Managing keyframes efficiently is vital for maintaining clean and optimized animations. KeyframeCleanerPro simplifies this process by allowing you to clean up unnecessary keyframes, remove duplicates, and optimize your animation workflow seamlessly.
๐๐๐๐ฉ ๐๐๐ฎ๐๐ง๐๐ข๐๐ฃ๐จ๐ฉ๐ง๐๐๐จ๐๐ง๐๐ง๐ค ๐๐๐๐๐ง๐จ:
Duplicate Keyframe Removal:ย Automatically detects and removes duplicate keyframes to streamline your animation curves.
Unnecessary Keyframe Cleanup:ย Identifies and deletes keyframes that do not contribute to the animation, reducing clutter.
Curve Optimization:ย Smoothens animation curves for more natural movements.
User-Friendly Interface:ย Intuitive UI designed to simplify the keyframe management process.
๐ ๏ธ ๐๐๐ฎ๐๐ง๐๐ข๐๐ฃ๐จ๐ฉ๐ง๐๐๐จ๐๐ง๐๐ง๐ค ๐๏ธโจ (๐ข๐๐ฎ๐.๐๐ข๐๐จ ๐๐๐ง๐จ๐๐ค๐ฃ):
import maya.cmds as cmds
def keyframeCleanerPro_maya_cmds(objects=None, optimize=True, remove_duplicates=True, remove_unnecessary=True):
ย ย ย ย """
ย ย ย ย Cleans up keyframes for multiple objects by removing duplicates and unnecessary keyframes,
ย ย ย ย and optimizes animation curves.
ย ย ย ย :param objects: <list> List of objects to clean. If None, use selected objects.
ย ย ย ย :param optimize: <bool> Optimize animation curves if True.
ย ย ย ย :param remove_duplicates: <bool> Remove duplicate keyframes if True.
ย ย ย ย :param remove_unnecessary: <bool> Remove unnecessary keyframes if True.
ย ย ย ย """
ย ย ย ย if objects is None:
ย ย ย ย ย ย ย ย objects = cmds.ls(selection=True, type='transform')
ย ย ย ย if not objects:
ย ย ย ย ย ย ย ย cmds.warning("No objects selected for keyframe cleaning.")
ย ย ย ย ย ย ย ย return
ย ย ย ย for obj in objects:
ย ย ย ย ย ย ย ย attrs = cmds.listAttr(obj, keyable=True)
ย ย ย ย ย ย ย ย if not attrs:
ย ย ย ย ย ย ย ย ย ย ย ย print("No keyable attributes found on '{0}'.".format(obj))
ย ย ย ย ย ย ย ย ย ย ย ย continue
ย ย ย ย ย ย ย ย for attr in attrs:
ย ย ย ย ย ย ย ย ย ย ย ย full_attr = "{0}.{1}".format(obj, attr)
ย ย ย ย ย ย ย ย ย ย ย ย keyframes = cmds.keyframe(full_attr, query=True)
ย ย ย ย ย ย ย ย ย ย ย ย if not keyframes:
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย continue
ย ย ย ย ย ย ย ย ย ย ย ย # Remove duplicate keyframes
ย ย ย ย ย ย ย ย ย ย ย ย if remove_duplicates:
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย unique_keyframes = sorted(set(keyframes))
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย duplicate_frames = [frame for frame in keyframes if keyframes.count(frame) > 1]
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย for frame in duplicate_frames:
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย cmds.cutKey(full_attr, time=(frame, frame))
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย print("Removed duplicate keyframe at frame {0} on '{1}'.".format(frame, full_attr))
ย ย ย ย ย ย ย ย ย ย ย ย # Remove unnecessary keyframes
ย ย ย ย ย ย ย ย ย ย ย ย if remove_unnecessary:
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย keyframes = cmds.keyframe(full_attr, query=True)
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย unique_keyframes = sorted(set(keyframes))
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย for i in range(1, len(unique_keyframes)-1):
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย prev_frame = unique_keyframes[i-1]
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย current_frame = unique_keyframes[i]
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย next_frame = unique_keyframes[i+1]
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย prev_val = cmds.getAttr(full_attr, time=prev_frame)
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย current_val = cmds.getAttr(full_attr, time=current_frame)
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย next_val = cmds.getAttr(full_attr, time=next_frame)
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย if prev_val == current_val == next_val:
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย cmds.cutKey(full_attr, time=(current_frame, current_frame))
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย print("Removed unnecessary keyframe at frame {0} on '{1}'.".format(current_frame, full_attr))
ย ย ย ย ย ย ย ย if optimize:
ย ย ย ย ย ย ย ย ย ย ย ย cmds.select(obj, replace=True)
ย ย ย ย ย ย ย ย ย ย ย ย cmds.keyTangent(inTangentType='linear', outTangentType='linear')
ย ย ย ย ย ย ย ย ย ย ย ย print("Optimized animation curves for '{0}'.".format(obj))
ย ย ย ย cmds.inViewMessage(amg='Keyframe cleaning complete.', pos='midCenter', fade=True)
ย ย ย ย print("KeyframeCleanerPro processing complete.")
def create_sample_scene():
ย ย ย ย """
ย ย ย ย Creates a sample scene with objects and keyframes, including duplicates and unnecessary keyframes.
ย ย ย ย """
ย ย ย ย # Create sample objects
ย ย ย ย obj1 = cmds.polyCube(name='TestCube1')[0]
ย ย ย ย obj2 = cmds.polySphere(name='TestSphere1')[0]
ย ย ย ย # Add keyframes with duplicates and unnecessary keyframes for obj1
ย ย ย ย cmds.setKeyframe(obj1, attribute='translateX', t=1, v=0)
ย ย ย ย cmds.setKeyframe(obj1, attribute='translateX', t=2, v=5)
ย ย ย ย cmds.setKeyframe(obj1, attribute='translateX', t=2, v=5) # Duplicate
ย ย ย ย cmds.setKeyframe(obj1, attribute='translateX', t=3, v=10)
ย ย ย ย cmds.setKeyframe(obj1, attribute='translateX', t=4, v=10) # Unnecessary
ย ย ย ย cmds.setKeyframe(obj1, attribute='translateX', t=5, v=15)
ย ย ย ย # Add keyframes with duplicates and unnecessary keyframes for obj2
ย ย ย ย cmds.setKeyframe(obj2, attribute='translateY', t=1, v=0)
ย ย ย ย cmds.setKeyframe(obj2, attribute='translateY', t=2, v=5)
ย ย ย ย cmds.setKeyframe(obj2, attribute='translateY', t=3, v=5) # Unnecessary
ย ย ย ย cmds.setKeyframe(obj2, attribute='translateY', t=4, v=10)
ย ย ย ย cmds.setKeyframe(obj2, attribute='translateY', t=4, v=10) # Duplicate
ย ย ย ย cmds.setKeyframe(obj2, attribute='translateY', t=5, v=15)
ย ย ย ย print("Sample scene created with objects and keyframes.")
def verify_cleanup(objects):
ย ย ย ย """
ย ย ย ย Verifies that the keyframes have been cleaned up as expected.
ย ย ย ย :param objects: <list> List of objects to verify.
ย ย ย ย """
ย ย ย ย for obj in objects:
ย ย ย ย ย ย ย ย attrs = cmds.listAttr(obj, keyable=True)
ย ย ย ย ย ย ย ย if not attrs:
ย ย ย ย ย ย ย ย ย ย ย ย print("No keyable attributes found on '{0}'.".format(obj))
ย ย ย ย ย ย ย ย ย ย ย ย continue
ย ย ย ย ย ย ย ย for attr in attrs:
ย ย ย ย ย ย ย ย ย ย ย ย full_attr = "{0}.{1}".format(obj, attr)
ย ย ย ย ย ย ย ย ย ย ย ย keyframes = cmds.keyframe(full_attr, query=True)
ย ย ย ย ย ย ย ย ย ย ย ย if not keyframes:
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย print("No keyframes found on '{0}'.".format(full_attr))
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย continue
ย ย ย ย ย ย ย ย ย ย ย ย print("Keyframes for '{0}': {1}".format(full_attr, keyframes))
def test_keyframeCleanerPro_maya_cmds():
ย ย ย ย """
ย ย ย ย Test function to demonstrate the keyframeCleanerPro_maya_cmds functionality.
ย ย ย ย """
ย ย ย ย # Create sample scene
ย ย ย ย create_sample_scene()
ย ย ย ย # Define objects to clean
ย ย ย ย objects = ['TestCube1', 'TestSphere1']
ย ย ย ย # Verify keyframes before cleaning
ย ย ย ย print("\nBefore Cleaning:")
ย ย ย ย verify_cleanup(objects)
ย ย ย ย # Call the keyframeCleanerPro function
ย ย ย ย keyframeCleanerPro_maya_cmds(objects=objects, optimize=True, remove_duplicates=True, remove_unnecessary=True)
ย ย ย ย # Verify keyframes after cleaning
ย ย ย ย print("\nAfter Cleaning:")
ย ย ย ย verify_cleanup(objects)
# Execute the test function
test_keyframeCleanerPro_maya_cmds() |
๐ ๏ธ ๐๐๐ฎ๐๐ง๐๐ข๐๐ฃ๐จ๐ฉ๐ง๐๐๐จ๐๐ง๐๐ง๐ค ๐๏ธโจ (๐๐ฎ๐๐๐๐2 ๐๐๐ง๐จ๐๐ค๐ฃ):
[Todayโs Challenge is to take this simple code to next level.. I am sharing images of these advanced codes...] |
๐ ๐๐๐๐ฉ ๐๐๐ฎ๐๐ง๐๐ข๐๐ฃ๐จ๐ฉ๐ง๐๐๐จ๐๐ง๐๐ง๐ค ๐๏ธโจ ๐๐๐๐๐ง๐จ:
Duplicate Keyframe Removal:ย Automatically detects and removes duplicate keyframes to streamline your animation curves.
Unnecessary Keyframe Cleanup:ย Identifies and deletes keyframes that do not contribute to the animation, reducing clutter.
Curve Optimization:ย Smoothens animation curves for more natural movements.
User-Friendly Interface:ย Intuitive UI designed to simplify the keyframe management process.
๐ง ๐๐๐ฎ ๐ฝ๐๐ฃ๐๐๐๐ฉ๐จ:
โข ๐ Boost Productivity:ย Save time on cleaning up keyframes manually by automating the process.
โข ๐ ๏ธ Enhance Workflow:ย Ideal for complex animations where numerous keyframes need management.
โข ๐ Improve Consistency:ย Ensures all selected objects have their keyframes cleaned uniformly, maintaining synchronization.
โข ๐ก User-Friendly Interface:ย Intuitive UI suitable for animators of all levels, making keyframe management seamless and efficient.
โจ Ready to Optimize Your Animations?
Try out KeyframeCleanerProย today and enhance your Maya workflow! Feel free to reach out or comment below to see it in action. Let's continue to elevate our Maya scripting together! ๐ช๐
๐๐ช๐๐๐ช'๐จ ๐๐๐ฃ๐ ๐จ :
โข YouTube Channel: https://www.youtube.com/@118subbuโข Vimeo:ย https://vimeo.com/subbu118โข Creature Rigging:ย https://www.creaturerigging.comโข Python Scripting:ย https://www.pythonscripting.comโข Hyper Rig:ย https://www.hyper-rig.com
#HappyScripting #MayaUI #KeyframeCleanerPro #PipelineOptimization #Maya #PythonScripting #MayaTools #VFX #3DAnimation #AnimationOptimization #Automation #WorkflowEnhancement #TechnicalArt #ScriptingTools
๐ ๏ธ๐ผ๐๐๐๐ฉ๐๐ค๐ฃ๐๐ก ๐๐๐ฅ๐จ:
Constraint Storage:ย For more advanced functionality, consider storing detailed constraint information before cleaning to allow for more precise reapplication.
Error Handling:ย The scripts include checks for object selection and handle cases with no keyframes gracefully.
Customization:ย Extend the tool to include options like specifying different cleaning intervals, handling custom attributes, or integrating with other animation tools.
Integration:ย Add this tool to your Maya shelf or integrate it into existing scripts for quick and easy access during your workflow.
Comments