RenderDocument() Feedback
-
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
-
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. -
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
-
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. -
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().
-
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
-
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. -
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?
-
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. -
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