On 12/08/2015 at 15:20, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 14
Platform: Windows ;
Language(s) : C++ ;
---------
I have been attempting to create a MaterialPreviewCustomGui object to display a torus. The code does not cause Cinema to crash, but it only results in the preview window being created without the torus. It runs through most of the Switch cases of the Message function from the ObjectPreviewShader, except that it will not run the MATPREVIEW_GENERATE_IMAGE option.
Code I'm using is below, this was mostly taken from an older post from an earlier version of Cinema.
#define ID_MEMSTAT 200000072
#include "c4d.h"
#include "gradientuserarea.h"
#include "c4d_symbols.h"
#include "customgui_matpreview.h"
#define OBJECT_PREVIEW_HOOK_ID 1000001
#define OBJECT_PREVIEW_SHADER_ID 1000002
#define COMMANDPLUGIN_ID 1000003
#define RDATA_RENDERASEDITOR 1000004
//////////////////////////////////////////////////////////////////////////////
///////////// shader class //////////////////////////////////////////////////
class ObjectPreviewShader : public ShaderData
{
public:
virtual Bool Message(GeListNode* node, LONG type, void* data)
{
switch (type)
{
case MATPREVIEW_GET_OBJECT_INFO:
{
GePrint("GET_OBJECT_INFO");
MatPreviewObjectInfo *info = static_cast<MatPreviewObjectInfo*>(data);
info->bHandlePreview = TRUE;
info->bNeedsOwnScene = TRUE;
info->bNoStandardScene = FALSE;
info->lFlags = MATPREVIEW_FLAG_HIDE_SCENES |
MATPREVIEW_FLAG_HIDE_ANIMATE |
MATPREVIEW_FLAG_HIDE_SCENE_SETTINGS |
MATPREVIEW_FLAG_HIDE_OPEN |
MATPREVIEW_FLAG_HIDE_SIZE;
break;
}
case MATPREVIEW_MODIFY_CACHE_SCENE:
{
GePrint("MODIFY_CACHE_SCENE");
MatPreviewModifyCacheScene *scene = static_cast<MatPreviewModifyCacheScene*>(data);
// Kidnap original object...
BaseObject *obj = scene->pDoc->SearchObject("Object");
obj->SetRenderMode(MODE_ON);
obj->SetEditorMode(MODE_ON);
// ...and insert our own
AutoAlloc<BaseObject> torus(Otorus);
torus->GetDataInstance()->SetReal(PRIM_TORUS_INNERRAD, 20.0);
torus->GetDataInstance()->SetReal(PRIM_TORUS_OUTERRAD, 60.0);
torus->SetRenderMode(MODE_ON);
torus->SetEditorMode(MODE_ON);
scene->pDoc->InsertObject(torus.Release(), obj, NULL);
break;
}
case MATPREVIEW_PREPARE_SCENE:
{
GePrint("PREPARE_SCENE");
MatPreviewPrepareScene* prepare = static_cast<MatPreviewPrepareScene*>(data);
prepare->bScenePrepared = TRUE;
break;
}
case MATPREVIEW_GENERATE_IMAGE:
{
GePrint("GENERATE_IMAGE");
MatPreviewGenerateImage* image = static_cast<MatPreviewGenerateImage*>(data);
if (image->pDoc)
{
LONG w = image->pDest->GetBw();
LONG h = image->pDest->GetBh();
BaseContainer bcRender = image->pDoc->GetActiveRenderData()->GetData();
bcRender.SetLong(RDATA_XRES, w);
bcRender.SetLong(RDATA_YRES, h);
bcRender.SetLong(RDATA_ANTIALIASING, ANTI_GEOMETRY);
if (image->bLowQuality)
{
bcRender.SetBool(RDATA_RENDERASEDITOR, TRUE);
}
image->pDest->Clear(0, 0, 0);
image->lResult = RenderDocument(image->pDoc, bcRender, NULL, NULL, image->pDest,
RENDERFLAGS_EXTERNAL | RENDERFLAGS_PREVIEWRENDER, image->pThread);
}
break;
}
case MATPREVIEW_GET_PREVIEW_ID:
{
GePrint("GET_PREVIEW_ID");
LONG *id = static_cast<LONG*>(data);
*id = 0;
break;
}
}
return TRUE;
}
virtual Vector Output(BaseShader *sh, ChannelData *cd) { return Vector(1.0, 0.2, 0.0); }
static NodeData *Alloc(void) { return gNew ObjectPreviewShader; }
};
/////////////////////////////////////////////////////////////////////////////////////
/////////// SceenHook class ////////////////////////////////////////////////////////
class ObjectPreviewHook : public SceneHookData
{
AutoAlloc<BaseShader> shad;
public:
ObjectPreviewHook() : shad(OBJECT_PREVIEW_SHADER_ID) {}
virtual Bool Init(GeListNode* node)
{
if(shad)
{
static_cast<BaseSceneHook*>(node)->InsertShader(shad);
}
return TRUE;
}
virtual void Free(GeListNode* node)
{
shad->Remove();
}
Bool InitPreviewData(MaterialPreviewData* preview_data, LONG dirtyCount)
{
return preview_data->Init(shad, dirtyCount);
}
static NodeData *Alloc(void) { return gNew ObjectPreviewHook; }
};
/////////////////////////////////////////////////////////////////////////
////////// dialog class /////////////////////////////////////////////////
class ObjectPreviewDialog : public GeDialog
{
enum
{
PREVIEW_ID = 1000,
GROUP_ID = 1001,
MIN_WIDTH = 100,
MIN_HEIGHT = 100,
};
private:
MaterialPreviewCustomGui *preview;
LONG dirtyCount;
public:
ObjectPreviewDialog() : preview(NULL), dirtyCount(0) {}
virtual void DestroyWindow(){ preview = NULL; }
virtual Bool CreateLayout(void);
virtual Bool InitValues(void);
virtual Bool Command(LONG id,const BaseContainer &msg);
void SetPreviewData(LONG dirtyCount); //A custom method
};
Bool ObjectPreviewDialog::CreateLayout(void)
{
SetTitle("Preview Gui");
GroupBegin(GROUP_ID, BFH_FIT | BFV_FIT, 1, 1, "Torus", 0);
GroupBorderSpace(2,2,2,2);
GroupBorder(BORDER_NONE | BORDER_WITH_TITLE);
{
BaseContainer settings;
settings.SetLong(MATPREVIEW_MIN_WIDTH, MIN_WIDTH);
settings.SetLong(MATPREVIEW_MIN_HEIGHT, MIN_HEIGHT);
//settings.SetBool(MATPREVIEW_NO_BORDER, TRUE);
preview = static_cast<MaterialPreviewCustomGui*>(AddCustomGui(PREVIEW_ID, CUSTOMGUI_MATPREVIEW, "", BFH_FIT | BFV_FIT,SizePix(MIN_WIDTH), SizePix(MIN_HEIGHT), settings));
}
GroupEnd();
SetPreviewData(dirtyCount);
return preview != NULL;
}
Bool ObjectPreviewDialog::InitValues(void)
{
//First call the parent instance
if(!GeDialog::InitValues()) return FALSE;
if(preview == NULL) return FALSE;
preview->SetLayoutMode(LAYOUTMODE_MAXIMIZED);
return TRUE;
}
Bool ObjectPreviewDialog::Command(LONG id,const BaseContainer &msg)
{
if(id == PREVIEW_ID)
{
SetPreviewData(++dirtyCount);
}
return TRUE;
}
//A custom method
void ObjectPreviewDialog::SetPreviewData(LONG dirtyCount)
{
if(preview == NULL) return;
TriState<GeData> t = preview->GetData();
GeData data = t.GetValue();
MaterialPreviewData *preview_data = static_cast<MaterialPreviewData*>(data.GetCustomDataType(CUSTOMDATATYPE_MATPREVIEW));
if(preview_data)
{
static_cast<ObjectPreviewHook*>( GetActiveDocument()->FindSceneHook(OBJECT_PREVIEW_HOOK_ID)->GetNodeData())->InitPreviewData(preview_data, dirtyCount);
preview_data->SetPreviewSize(MatPreviewSizeDefault);
preview_data->SetPreviewType(MatPreviewUser);
}
preview->SetData(data);
}
class MemStatCommand : public CommandData
{
private:
ObjectPreviewDialog dlg;
MaterialPreviewCustomGui *preview;
LONG dirtyCount;
public:
virtual Bool Execute(BaseDocument *doc);
virtual Bool RestoreLayout(void *secret);
};
Bool MemStatCommand::Execute(BaseDocument *doc)
{
ObjectPreviewDialog dlg;
return dlg.Open(DLG_TYPE_ASYNC, COMMANDPLUGIN_ID, -1, -1, 300, 150);
}
Bool MemStatCommand::RestoreLayout(void *secret)
{
return dlg.RestoreLayout(ID_MEMSTAT,0,secret);
}
Bool RegisterMemoryStat(void)
{
RegisterShaderPlugin(OBJECT_PREVIEW_SHADER_ID, "Object Preview", PLUGINFLAG_HIDE, ObjectPreviewShader::Alloc, "", 0);
RegisterSceneHookPlugin(OBJECT_PREVIEW_HOOK_ID, "Object Preview", PLUGINFLAG_HIDE, ObjectPreviewHook::Alloc, EXECUTIONPRIORITY_INITIAL, 0, NULL);
return RegisterCommandPlugin(ID_MEMSTAT,"Preview GUI",0, AutoBitmap("icon.tif"), String("My Simple Dialog"),gNew MemStatCommand);
}
I've been looking at this for a while now and any help would be really appreciated.
Johan