Start render in PictureViewer at the moment when a certain file has changed



  • Hi All,

    First - i'm trying Python since two days - so my brain is pretty empty to this topic :-)

    I've a textfile *.txt where are some values stored.
    Once a day one of the values is going to change.
    the values are being imported in cinema 4d (via python-node in expresso) where they are mapped on some object parameters.

    Now my issue:
    how can i get cinema 4d to start the render after the change in the values of the textfile is occured and the parameter has also done its correspondent change?

    two things are seeming to be a problem for me:
    · how i get a continuous check for the textfile has changed?
    · how i can start the CallCommand(12099) #for RenderInPictureviewer from this code

    Hope you can help me
    Thanks a lot so far

    Matthias



  • Hi @daltonmonaie for a 2day programmer it's indeed a not easy task to do and you will need to train a bit or be ready to read/learn a lot before doing what you want.

    May I ask you when should you monitor a file for a change? Only when a given scene is opened or as long as Cinema 4D is opened?

    With that's said the C4D API does not provide anything for tracking file change, you have to do it yourself. You can find information about it https://blog.magrathealabs.com/filesystem-events-monitoring-with-python-9f5329b651c3

    But you will need to get pip working in order to install watchdog module.
    For that you should use c4dpy as explained in the c4dpy manuel.
    And run the get-pip.py with c4dpy in order to install pip.
    Then you will be able to write c4dpy -m pip install watchdogso pip will download and install watchdog module so you will be able to import and use watchdog in your script.

    Then regarding how to trigger a render, the best way to either directly call the command with CallCommand or either run RenderDocument to render the document and then display the result into the PictureViewer.

    But please consider to do it step by step and firstly get the file monitor to works then the render is the other part.

    Cheers,
    Maxime.



  • Hi Maxime,

    Thank you very much for taking your time answering my questions.

    It was quiet a journey for me to install the watchdog module - but i've got it. Now it's there, inside my Cinema4D-Skript-Manager :-) yay!

    First, as you suggested, i'm just care about this watchdog.thingy and try to find out, how to use this. I think/hope the rest of my stuff is not that hard to do, because it seems much simpler to me. (In some pretty primitve skript-stuff i've got some experience. - so as i've got the text-import working in the Python-Expresso-Node.)

    ...but this watchdog.stuff seems to start a background-routine witch is not directly dependent to the Cinema4D-Environment. But i can start it from the Skript Manager and i can get the file-change event back into the skript - am i right there? ...or do i think wrong about?

    I've found this manual for watchdog:
    https://pythonhosted.org/watchdog/quickstart.html#a-simple-example

    If you should have some more time: Could you give me a hint, how to implement this inside my c4d-script?

    Once again: Thank you so far
    Matthias



  • The main issue is that a GvNode or a Script Manager is not persistent. Meaning, for example, the script manager.
    Things only exist for the time you execute your command. At the moment your script finishes being executed everything is deleted this is due to the GIL.

    Same things for Xpresso Node (GvNode) the python code is only executed when the scene calls the execution of the Xpresso tag. So that's means again the data are somehow not persistent. A quick hack is to define a variable as global so you will be available to access this variable along with multiple executions of the Xpresso Tag see Python Global, Local and NonLocal variable.

    So with that's said, an important thing to understand, Xpresso Tag execution and actually the whole scene execution (aka retrieving the cache of objects, executing tags, Xpresso Tag, Xpresso Node) is multithreaded. And as described in the
    Threading Information, you can't do whatever you want in a thread and for example trigger a render have no sense. Here some background about what is a thread Thread Wikipedia.
    So some stuffs are executed in parallel,in your case, it will make no sense to render the scene (from the execution of Xpresso Tag) if the cube geometry is not yet created.

    So that means we need a way to say once you have finished to build the scene, do something. Such things in Cinema 4D is usually done with Message and message stack. So typically in your Xpresso node you will put a MessageID on a stack of others Cinema 4D MessageId that will be executed at the end of the current scene execution (actually a scene execution is also launched from another message, so literally Cinema 4D has a list of operation to do in the main thread and it simply iterate over theses things to do).

    Then you will create a MessageData plugin in order to receive this message, that will be executed in the main thread and there you will be able to render the document.

    So long story short. Here is a scene file with a python node the code is inspired by this post in stackoverflow:
    test.c4d

    And the plugin to create your own message that will render into the picture viewer. You have to put it into your plugin folder and name it "WhateverYouWant.pyp"

    import c4d
    
    # Make sure to have an Unique ID from https://plugincafe.maxon.net/c4dpluginid_cp
    PLUGIN_ID = 1000001
    
    class MyMessagePlugin(c4d.plugins.MessageData):
    	def CoreMessage(self, id, msg) :
    		if id == PLUGIN_ID:
    
    			# Render the document if there is not actually another render running
    			if not c4d.CheckIsRunning(c4d.CHECKISRUNNING_EXTERNALRENDERING):
    				c4d.CallCommand(12099)
                
    		return True
    
    if __name__ == "__main__":
        c4d.plugins.RegisterMessagePlugin(PLUGIN_ID, "MyMessagePlugin", 0, MyMessagePlugin())
    

    I know it can be a bit hard for a beginner if you have any questions, please don't hesitate to ask.
    Cheers,
    Maxime



  • Hi Maxime,

    Wow! I'm completly blown away :-)

    What would be, one asks you to do a full job and not only to give a hint? World Peace?
    So you've done pretty much the whole work for me - just out of kindness - Thank you so much!

    Yes, it works now exactly as i wanted - so i'm going to use my spared time to explore your solution and try to understand it more deeply than just seeing: "Ah, here i've to put my directory in and here i have to generate a text file with this text inside..." :-)

    Thanks again &
    i wish you beautifull days in your life
    when there should be anything i can do for you - just say it (most i can do is 3D-Graphics-Stuff)
    for sure, when this project i'm working on is finaly done in every aspect i'll give you a message, so you can at least see the result. But that will take some months.

    Matthias


Log in to reply