Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Register
    • Login

    Disable all animation in document

    Scheduled Pinned Locked Moved Cinema 4D SDK
    python2026windows
    5 Posts 3 Posters 42 Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • C Offline
      ceen
      last edited by

      Hi,
      is there a way to disable in Dope sheet all animation in a document? Bascially trigger the Eye Icon function in timeline Summary

      AnlvA 1 Reply Last reply Reply Quote 0
      • AnlvA Offline
        Anlv @ceen
        last edited by

        @ceen Hi, The Summary row mey only a UI aggregate; it is not a single CTrack that can be switched directly.
        To reproduce its Animation switch, collect the real CTrack objects and set their c4d.ID_CTRACK_ANIMOFF value:

        # True = animation enabled, False = animation disabled
        track[c4d.ID_CTRACK_ANIMOFF] = False
        

        This does not delete keyframes and does not hide Timeline rows. Do not use NBIT_TLx_HIDE for this, because those flags only hide rows in the Timeline.
        A complete document-wide solution must also traverse Motion Sources in doc.GetNLARoot() . Add Motion Source moves/copies animation into that separate NLA hierarchy, so iterating only normal scene objects and tags will miss tracks such as Time and 2D Tracks.

        It should be noted that doc.GetNLARoot() is marked as Private in the SDK, and I'm not sure whether it should be used.

        """Toggle the Summary Animation switch for all collected CTracks."""
        
        import c4d
        
        
        def iter_nodes(node):
            while node:
                yield node
                yield from iter_nodes(node.GetDown())
                node = node.GetNext()
        
        
        def main():
            doc = c4d.documents.GetActiveDocument()
            tracks, seen = [], set()
        
            def add_tracks(owner):
                for track in (owner.GetCTracks() or []) if owner else []:
                    if id(track) not in seen:
                        seen.add(id(track))
                        tracks.append(track)
        
            def add_tree(root, include_tags=False):
                for node in iter_nodes(root):
                    add_tracks(node)
                    if include_tags:
                        for tag in node.GetTags() or []:
                            add_tracks(tag)
        
            add_tracks(doc)
            add_tree(doc.GetFirstObject(), include_tags=True)
        
            material = doc.GetFirstMaterial()
            while material:
                add_tracks(material)
                add_tree(material.GetFirstShader())
                material = material.GetNext()
        
            render_data = doc.GetFirstRenderData()
            while render_data:
                add_tracks(render_data)
                video_post = render_data.GetFirstVideoPost()
                while video_post:
                    add_tracks(video_post)
                    video_post = video_post.GetNext()
                render_data = render_data.GetNext()
        
            layer_root = doc.GetLayerObjectRoot()
            add_tree(layer_root.GetDown() if layer_root else None)
        
            # Private API, but required for Add Motion Source tracks in C4D 2026.
            add_tree(doc.GetNLARoot().GetDown(), include_tags=True)
        
            enabled = any(track[c4d.ID_CTRACK_ANIMOFF] for track in tracks)
            for track in tracks:
                track[c4d.ID_CTRACK_ANIMOFF] = not enabled
            c4d.EventAdd()
        
        
        if __name__ == "__main__":
            main()
        

        Cheers,
        Anlv

        ferdinandF 1 Reply Last reply Reply Quote 1
        • ferdinandF Offline
          ferdinand @Anlv
          last edited by ferdinand

          Hello @ceen,

          Yes, this is possible. @Anlv is right that ID_CTRACK_ANIMOFF is the toggle you are looking for (thank you for helping out!). You can then either combine it with manual scene traversal code, or use mxutils.RecurseGraph which is for most users probably the simpler option when they do not have intimate knowledge of the Cinema scene graph.

          Cheers,
          Ferdinand

          """Loops over all tracks in the scene and toggles their animation state.
          
          I.e., running this once will disable all tracks, running it again will enable all tracks, and so on.
          """
          
          import c4d
          import mxutils
          
          doc: c4d.documents.BaseDocument  # The currently active document.
          op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.
          
          def main() -> None:
              """Called by Cinema 4D when the script is being executed.
              """
              # We walk the document using RecurseGraph, finding all tracks in the scene, no matter where they
              # are hiding. This is a relatively inefficient call as we really walk everything, and experts
              # could fine tune this. But for a simple script like this or any code that is not performance 
              # critical, this is just fine.
              for track in mxutils.RecurseGraph(doc, yieldBranches=True, yieldHierarchy=True, nodeFilter=[c4d.CTbase]):
                  track[c4d.ID_CTRACK_ANIMOFF] = not track[c4d.ID_CTRACK_ANIMOFF]
          
              c4d.EventAdd()
          
          
          if __name__ == '__main__':
              main()
          

          MAXON SDK Specialist
          developers.maxon.net

          AnlvA 1 Reply Last reply Reply Quote 1
          • AnlvA Offline
            Anlv @ferdinand
            last edited by

            Hi @ferdinand,

            using the mxutils.RecurseGraph method is much clearer and simpler. Thank you, I've learned something new again.

            Cheers,
            Anlv

            1 Reply Last reply Reply Quote 0
            • C Offline
              ceen
              last edited by

              Hi,
              @ferdinand and @Anlv this is most awesome! All way beyond my capablities so thanks a lot for the scripts!

              1 Reply Last reply Reply Quote 0
              • First post
                Last post