Python: How to inject code into a Python tag?
-
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?
-
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'sStartUndo()
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
-
@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?:
- Start Cinema 4D
- Start VSCode
- Connect VsCode and Cinema 4D together
- Create a new Empty document in VsCode
- Write some stuff into it
- 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. -
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.