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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    RenderDocument() Feedback

    SDK Help
    0
    10
    852
    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.
    • H
      Helper
      last edited by

      On 03/02/2016 at 13:50, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   13 
      Platform:   Windows  ;   
      Language(s) :     C++  ;

      ---------
      Hi,

      It seems like once we execute the RenderDocument() function. We go into a sort of information blackout while it does it's thing.
      Is there a way to monitor what it's doing (like the frame it's currently rendering) while the RenderDocument() function is running?

      Do we need to use some kind of Callback for this?

      -ScottA

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 03/02/2016 at 14:20, xxxxxxxx wrote:

        There doesn't seem to be a callback of any kind. I think you should just
        render each frame with a separate call to RenderDocument(). Actually, I
        was surprised to read it would render multiple frames.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 03/02/2016 at 14:32, xxxxxxxx wrote:

          In R17 there is this: WriteProgressHook()
          In R13 there is this: SaveCallbackImageFunc(). But it's marked private.

          I've never used these. So I have no idea if these can be used to get information from RenderDocument() or not?

          -ScottA

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 03/02/2016 at 18:29, xxxxxxxx wrote:

            Uh I Forgot the C++ RenderDocument() takes. a whole bunch of
            additional paramters compared to the Python version. As you point
            out, there certainly are callbacks available and my statement above
            is false.

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 04/02/2016 at 01:57, xxxxxxxx wrote:

              Hi,

              You can use the ProgressHook callback for the RenderDocument() call ( prog parameter).
              It gives the render progress value and type.

              WriteProgressHook is only called during the write process of RenderDocument().

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 04/02/2016 at 10:17, xxxxxxxx wrote:

                I need a little help with that Callback.
                Callbacks are my kryptonite. And of course there is no information on this in the forum database.

                I'm using an ASYNC GeDialog plugin with a button to execute the rendering process.
                The render settings and RenderDocument() function are in the Command() method in my plugin.
                I think I have written the callback function correctly. But I'm not 100% sure.

                template<class TYPE> void pr(Real p, RENDERPROGRESSTYPE progress_type, void *private_data)  
                {  
                  GePrint(RealToString(p));  
                }
                

                But I can't figure out how to call to that Callback in my RenderDocument() function.
                This doesn't work. "pr" throws an error.

                RenderDocument(GetActiveDocument(), rdata, pr, NULL, bmp, RENDERFLAGS_EXTERNAL, NULL);
                

                I've tried various ways to create a pointer that points to the Callback. But I just can't get it right.
                What am I missing, or doing wrong?

                -ScottA

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 04/02/2016 at 13:28, xxxxxxxx wrote:

                  Why are you declaring the function as a template? You could use
                  something like pr<Int32>, that should work. Better you get rid of the
                  template part at all though.

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 04/02/2016 at 14:08, xxxxxxxx wrote:

                    Because that is how I was told to use a templated Callback.
                    Here is an example of using the GeDynamicArrayCallback() which works

                    //GeDynamicArrayCallback is declared as:  typedef void GeDynamicArrayCallback(VLONG index, TYPE *value, void *data);  
                    //First you have to define a global callback function like this  
                      
                    template<class TYPE> void myArrayCallback(VLONG index, TYPE *value, void *data)  
                    {   
                      *value *= 2;   //value is the current value at index in the dynamic array  
                    }  
                      
                    //Then pass that function (myArrayCallback) to the array in your method where your array is  
                    Bool myDialog::Command(LONG id,const BaseContainer &msg)  //This is where the code that does something goes  
                    {  
                      GeDynamicArray<LONG> myarray(3);  
                      myarray[0] = 100;  
                      myarray[1] = 200;  
                      myarray[2] = 300;  
                      
                      myarray.DoToAll(&myArrayCallback, NULL);  
                      
                      return TRUE;  
                    }
                    

                    But this code doesn't help me with the ProgressHook callback.
                    Because I have no class member to call it with.

                    If the ProgressHook callback works differently then I need to know why it's different. And how to use it properly.
                    I've been trying to use Google to help figure this out. But MAXON writes their callbacks using void *data. And I can't find anyone posting code like that.
                    Every time I need to use a C4D SDK callback. I get entangled in this "How do I use This thing?" battle.
                    The code I find on the web and in my C++ books isn't much help understanding how MAXON is doing them.

                    -ScottA

                    *Edit-- BTW. Thanks for the hint Niklas. This works when used with my callback function:
                    RenderDocument(GetActiveDocument(), rdata, pr<Real>, NULL, bmp, RENDERFLAGS_EXTERNAL, NULL);

                    Is there anything that we can do with void *private_data?

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 05/02/2016 at 01:41, xxxxxxxx wrote:

                      Hi Scott,

                      Don't mix GeDynamicArrayCallback and ProgressHook callbacks.
                      GeDynamicArrayCallback is a special case because callbacks don't usually use templates.
                      ProgressHook isn't a templated callback because it has no TYPE parameter.

                      So here's how it can be defined:

                      static void RenderProgressCallback(Float p, RENDERPROGRESSTYPE progress_type, void* private_data)
                      {
                      	// Show progress depending on p and progress_type
                      	// Use private_data to access data from your code
                      }
                      

                      void* private_data of the ProgressHook parameter is simply passed from the void* private_data parameter of the call to RenderDocument().
                      This can be set to a pointer to an object instance so that it can be accessed from the ProgressHook.

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 05/02/2016 at 08:03, xxxxxxxx wrote:

                        Thanks for the explanation about the callbacks Yannick.
                        The SDK is so frustrating because it's full of these odd things in it that I don't normally run into out in the wild.
                        But learning these things will make me a better coder.

                        Can you tell me what is the benefit for pointing to an object from inside of the ProgressHook?
                        I can't think of why that would be useful. But the person that wrote this must have had a good reason for putting it in there.
                        I feel like I'm not taking advantage of something that might be useful to me.

                        Here's a stripped down example.
                        I'm fuzzy on how, and why, to use void *private_data.

                        static void rpCallback(Real p, RENDERPROGRESSTYPE progress_type, void *private_data)  
                        {  
                          renderProg = p;   //renderProg is a global variable I'm using to communicate with the dialog  
                          GePrint(RealToString(p));  
                          
                          BaseObject *obj = GetActiveDocument()->GetFirstObject();  
                          if (!obj)return;  
                          String objName = obj->GetName();  
                          
                          //Just doing something to the object while rendering  
                          obj->SetRelRot(renderProg+10);  
                          obj->Message(MSG_UPDATE);  
                          
                          private_data = obj;  //<---Am I using this correctly?  
                        }  
                          
                        ...  
                          
                        Bool MyDialog::Command(LONG id,const BaseContainer &msg)  
                        {  
                          //This is in my button code  
                          
                          //Execute the rendering and monitor it's progress using the ProgressHook callback "rpCallback"  
                          //Am I calling it correctly?  
                          RenderDocument(GetActiveDocument(), rdata, rpCallback, rpCallback, bmp, RENDERFLAGS_EXTERNAL, NULL);  
                          
                          EventAdd();  
                          return TRUE;  
                        }
                        

                        This code works without any errors or crashes.
                        But the object never gets rotated until after the rendering is finished.
                        So I'm not sure if I'm using the private_data part correctly?

                        -ScottA

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