Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Login

    Python: How to inject code into a Python tag?

    Cinema 4D SDK
    python 2024
    3
    4
    587
    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.
    • gaschkaG
      gaschka
      last edited by

      I'm working on a script, which creates bunch of objects in the OM and then adds a Python Tag to one of them, to control my new objects with a script.
      First I tried the following approach, which did not always work reliable from VSC, especially after restarting C4D. My impression was, that I had to open the linked file in the Script Manager once to be able to use the Execute in C4D command in VSC with that file linked successfully:

      def add_python_tag(obj, config):
          tag_file = os.path.join(os.path.dirname(__file__), "file_with_code_for_the_python_tag.py")
          
          if not obj or not os.path.exists(tag_file):
              return
          
          python_tag = c4d.BaseTag(c4d.Tpython)
          with open(tag_file, 'r') as f:
              python_code = f.read()
      
          python_tag[c4d.TPYTHON_CODE] = python_code
          obj.InsertTag(python_tag)
          
          c4d.EventAdd()
      

      So I'm using this approach now, but this feels very hacky, and I loose the syntax highlighting for all the injected code, which makes me still maintain the file above and then copy and paste into the string:

      def add_python_tag(obj):
          if not obj:
              return
      
          python_tag = c4d.BaseTag(c4d.Tpython)
      
          python_code = """
      
      import c4d
      
      def main():
          # my code for the Python tag
      
      
      # Execution
      if __name__ == '__main__':
          main()
      
      """
      
          python_tag[c4d.TPYTHON_CODE] = python_code
          obj.InsertTag(python_tag)
      
          c4d.EventAdd()
      

      I'm new to all of this, so I want to ask, if this a good practice, or are there other more slick ways to approach this?

      bacaB M 2 Replies Last reply Reply Quote 0
      • bacaB
        baca @gaschka
        last edited by

        Hi @gaschka

        Nothing really confusing in your code, python is not very strict...

        I can only suggest to move out constants of the function scope,
        and there are plenty space to add verifications...

        And c4d.EventAdd() might be executed just once, in the end of the parent function where you creating objects and attaching tags
        Also don't forget to use document's StartUndo() AddUndo() EndUndo() methods when creating your objects.

        SOME_PYTHON_TAG_CODE = """
        import c4d
        
        def main():
            # my code for the Python tag
        
        # Execution
        if __name__ == '__main__':
            main()
        """
        
        def add_python_tag(obj):
            if not isinstance(obj, c4d.BaseObject):
                return None
        
            python_tag = obj.MakeTag(c4d.Tpython)
            python_tag[c4d.TPYTHON_CODE] = SOME_PYTHON_TAG_CODE
        
            return python_tag
        
        1 Reply Last reply Reply Quote 1
        • M
          m_adam @gaschka
          last edited by

          @gaschka said in Python: How to inject code into a Python tag?:

          First I tried the following approach, which did not always work reliable from VSC, especially after restarting C4D. My impression was, that I had to open the linked file in the Script Manager once to be able to use the Execute in C4D command in VSC with that file linked successfully

          It will be nice if you have clear reproduction step, if I understand correctly you did the following, is that correct?:

          1. Start Cinema 4D
          2. Start VSCode
          3. Connect VsCode and Cinema 4D together
          4. Create a new Empty document in VsCode
          5. Write some stuff into it
          6. Execute it from VsCode via the Execute in C4D command.

          What confuse me is when you say "especially after restarting C4D. " So the first time it work, but not the next one? At least here its working as expected. May I ask which version of Cinema 4D and VsCode extension do you use?

          @gaschka said in Python: How to inject code into a Python tag?:

          So I'm using this approach now, but this feels very hacky, and I loose the syntax highlighting for all the injected code, which makes me still maintain the file above and then copy and paste into the string

          This is correct, if you want the ability you can save the file somewhere and just read it like so on the fly:

          import os
          
          def get_python_code():
              s = ""
              
              # Get the path of the current directory, requiere the current script to be saved
              currentDirectory = os.path.dirname(__file__)
              
              # Retrieve the file path of a file called "other_file.py" located in the same directory as this one
              otherFileFullPath = os.path.join(currentDirectory, "other_file.py")
              
              # Read the file
              with open(otherFileFullPath) as file:
                  s = file.read()
                  
              return s
          
          def add_python_tag():
              if not isinstance(obj, c4d.BaseObject):
                  return None
          
              python_tag = obj.MakeTag(c4d.Tpython)
              python_tag[c4d.TPYTHON_CODE] = get_python_code()
          
              return python_tag
          
          if __name__ == '__main__':
              add_python_tag()
          

          Cheers,
          Maxime.

          MAXON SDK Specialist

          Development Blog, MAXON Registered Developer

          1 Reply Last reply Reply Quote 1
          • gaschkaG
            gaschka
            last edited by

            Thanks to you both for your answers.

            @m_adam Regarning my issue with the file linking, I'll try to come up with a procedure for reproduction of my issue soon: It was quite random, but I was in the flow of writing my script, so I circumvented with the string solution, but I would prefer the file solution for sure.

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