I see, thank you for the answer.
I have used a texbox customGui inside my iCustomGui, but for some reasons, it seems that I can not apply a shader to it.
The attribute is shown on the UI but does not seem to be functional.
On my iCustomGui::CreateLayout(), I have added it together with some other attributes, but this is the only one that is not functional.
TexBoxGui* list = (TexBoxGui*)AddCustomGui(COLOR_ID + i, CUSTOMGUI_TEXBOX, String(), BFH_SCALEFIT, 0, 0, settings);
Is there something I am missing?
Trying to "force" the UI update using EventAdd() after setting the node dirty still does not trigger GetDDescription function. I thought this was what I was missing but seems there is something else.
I am not 100% sure if it will be the final workflow, but for now, that's our intention. We are trying to keep a uniform UI on all DCCs (as in the image below) and this way has proven to be efficient.
Of course, this will not be the only way to launch a render, but if we see it to be efficient in Cinema4D too then yes this will also be a way we will keep.
Unfortunately, our C4D plugin is too far away from other plugins that we support on other DCCs, and there's still a lot to do.
As for the buttons' workflow, it would be:
Clicking Render will set the button to Abort Render and make the other two buttons insensitive until rendering finishes (that is why I want to update the UI after rendering is finished), or abort render is clicked which this updates the UI fine.
The same goes for the other two buttons (Start IPR -> Abort IPR and make the other two buttons insensitive until you abort it).
BaseDocument* doc = GetActiveDocument();
BaseDocument* renderdoc = (BaseDocument*) doc->GetClone(COPYFLAGS::DOCUMENT, nullptr);
RenderData* rd = renderdoc->GetActiveRenderData();
If this is what you mean for getting the rendering document, I am using this way on my original code. I am not sure if the issue is related to this.
Tried that by still the same :/.
I am using R21.027.
From python console, it worked fine. After setting the node dirty, getDDescription function got executed. But I wonder what is different as the same event is being executed when the rendering finishes and the node is set Dirty except that getDDescription does not get executed after.
Hello, here is the code.
return RegisterVideoPostPlugin(ID_RENDERSETTINGS, "3Delight"_s, PLUGINFLAG_VIDEOPOST_ISRENDERER, RenderSettings::Alloc, "dlrendersettings"_s, 0, 0);
The message is sent through RenderManager which is inherited from Message Data.
Bool RenderManager::CoreMessage(Int32 id, const BaseContainer& bc)
//This is executed when rendering has finished.
if (id == DL_FRAME_COMPLETED)
ApplicationOutput("Frame has completed Rendering");
BaseDocument* doc = GetActiveDocument();
RenderData* rd = doc->GetActiveRenderData();
bool has_vp = false;
BaseVideoPost* vp = rd->GetFirstVideoPost();
while (vp != NULL && !has_vp)
has_vp = (vp->GetType() == ID_RENDERSETTINGS); // Look for rendersettings
vp = vp->GetNext();
//Message to VP is sent correctly. This triggers the RenderSettings::Message function for case DLRenderFinished.
parser = 0x0;
Yes, I am aware of that part, I had already registered my VideoPost Plugin and ID_RENDERSETTINGS is the plugin ID I am using for that (Loading it on GetDDescription which loads fine), but I had not included register function on my sample code.
Also, GetDDescription is being called when I click the 'render' button on my Render Settings (VideoPost) but the problem is that it does not get called when the rendering has finished (for this to happen I don't interact with the UI at all), but only set my node dirty, thinking it would automatically trigger GetDDescription function to be called.
Defined the parent to 'ID_VIDEOPOSTPROPERTIES' as suggested but this did not help too.
Hello, here is a part of the code I am using.
Note that my RenderSettings class is inherited from VideoPostData
static const Int32 DLRenderFinished = 10000;
Bool RenderSettings::Init(GeListNode* i_node)
render_started = false;
Bool RenderSettings::GetDDescription(GeListNode* i_node, Description* i_description, DESCFLAGS_DESC& i_flags)
const DescID* singleid = i_description->GetSingleDescID();
const Int32 ID = DL_RENDER_BUTTON;
const DescID cid = DescLevel(ID, DTYPE_BUTTON, 0);
if (!singleid || cid.IsPartOf(*singleid, nullptr))
BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BUTTON);
bc.SetString(DESC_NAME, "Stop Render"_s);
bc.SetString(DESC_NAME, "Start Render"_s);
i_description->SetParameter(cid, bc, DescLevel(ID_OBJECTPROPERTIES));
i_flags |= DESCFLAGS_DESC::LOADED;
return SUPER::GetDDescription(i_node, i_description, i_flags);
Bool RenderSettings::Message(GeListNode* i_node, Int32 i_type, void* i_data)
DescriptionCommand* dc = (DescriptionCommand*) i_data;
const Int32 id = dc->_descId.id;
if (id == DL_RENDER_BUTTON)
//Start rendering and show stop render button
render_started = true;
//DLRenderFinished is executed successfully when rendering is finished, but this does not trigger an update on the UI.
return SUPER::Message(i_node, i_type, i_data);
I have a scenario where I am trying to trigger an update after a specific message but setting the node dirty does not seem to trigger this update.
I am doing the update on getDDescription() function and set the flag in NodeData message function i_node->SetDirty(DIRTYFLAGS::DESCRIPTION);
Although the node has been successfully set dirty, it does not execute getDDescription() function after that.
Am I missing something?