Hello,
I have ObjectPlugin that contain a sphere object with texture tag, and from the NodeData.Message() I want to run my "Texture Baker" CommandData plugin to bake the sphere object texture.
The Texture Baker work on default sphere object but on plugin object I don't know how to do to access the sphere object inside the plugin object cache.
BaseObject* MyObject::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
{
if (!op)
return BaseObject::Alloc(Onull);
Bool bIsDirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA);
if (!bIsDirty)
return op->GetCache(hh);
BaseContainer* objectData = op->GetDataInstance();
if (!objectData)
return BaseObject::Alloc(Onull);
BaseObject* container = BaseObject::Alloc(Onull);
BaseObject* sphere = BaseObject::Alloc(Osphere);
if (!container || !sphere)
return BaseObject::Alloc(Onull);
container->SetName("Container");
sphere->SetName("BakerObject");
Float rad = objectData->GetFloat(HDRISGBAKEROBJECT_RAD);
sphere->SetParameter(PRIM_SPHERE_TYPE, 2, DESCFLAGS_SET_0);
BaseTag* phongTag = sphere->MakeTag(Tphong);
phongTag->SetParameter(PHONGTAG_PHONG_ANGLELIMIT, Bool(true), DESCFLAGS_SET_0);
// create the texture tag
TextureTag* const textureTag = static_cast<TextureTag*>(sphere->MakeTag(Ttexture));
if (textureTag == nullptr)
return container;
// apply material
BaseDocument* doc = hh->GetDocument();
BaseMaterial* material = doc->SearchMaterial("My Material");
if (!material)
return container;
textureTag->SetMaterial(material);
sphere->InsertUnder(container);
return container;
}
I found this Topic and I wanted to try the suggested solution, but this crashing the c4d application.
Here how I use it
Bool MyObject::Message(GeListNode* node, Int32 type, void* data)
{
switch (type)
{
case MSG_DESCRIPTION_COMMAND:
{
DescriptionCommand* dc = (DescriptionCommand*)data;
const Int32 id = dc->id[0].id;
switch (id)
{
case MYOBJECT_TEXTURE_BAKER:
{
// allocate a temp doc
AutoAlloc<BaseDocument> tempDoc;
if (!tempDoc)
return false;
const Filename path = GeGetStartupWritePath() + Filename("tex") + Filename("texture_baker");
tempDoc->SetDocumentPath(path);
// allocate a primitive sphere
BaseObject* primSphere = BaseObject::Alloc(Osphere);
if (!primSphere)
return false;
// obtain the polygon representation
PolygonObject* polygonSphere = ToPoly(primSphere);
// insert into the temp doc
tempDoc->InsertObject(polygonSphere, nullptr, nullptr);
// allocate a texture tag
TextureTag* sphereTextureTag = TextureTag::Alloc();
if (!sphereTextureTag)
return false;
// set the texture tag params
sphereTextureTag->SetParameter(DescID(TEXTURETAG_PROJECTION), TEXTURETAG_PROJECTION_CUBIC, DESCFLAGS_SET_0);
// insert into the polygonSphere
polygonSphere->InsertTag(sphereTextureTag);
// allocate a material
AutoAlloc<Material> sphereMaterial;
if (!sphereMaterial)
return false;
// get the BaseContainer of the material
BaseContainer *sphereMaterialBC = sphereMaterial->GetDataInstance();
if (!sphereMaterialBC)
return false;
// allocate the colorizer shader
AutoAlloc<BaseShader> colorizerShader(Xcolorizer);
if (!colorizerShader)
return false;
// retrieve the BaseContainer of the colorizer
BaseContainer* colorizerShaderBC = colorizerShader->GetDataInstance();
if (!colorizerShaderBC)
return false;
// allocate the bitmap shader
AutoAlloc<BaseShader> bitmapShader(Xbitmap);
if (!bitmapShader)
return false;
// retrieve the BaseContainer of the bitmap
BaseContainer* bitmapShaderBC = bitmapShader->GetDataInstance();
if (!bitmapShaderBC)
return false;
Filename bitmapFilename("bitmap.jpg");
// set the filename of the bitmap shader
// NOTE: the file should reside in the application directory if the project files has not been
// saved on disk or inside the /tex folder where the project files resides
bitmapShaderBC->SetFilename(BITMAPSHADER_FILENAME, bitmapFilename);
// set the texture link of the colorizer shader to the bitmapShader
colorizerShaderBC->SetLink(SLA_COLORIZER_TEXTURE, bitmapShader);
colorizerShader->InsertShader(bitmapShader.Release());
// set the color link of the material to the colorizer shader
sphereMaterialBC->SetLink(MATERIAL_COLOR_SHADER, colorizerShader);
sphereMaterial->InsertShader(colorizerShader.Release());
// update
sphereMaterial->Message(MSG_UPDATE);
sphereMaterial->Update(true, true);
// insert the material and set the texture tag to use this material
sphereTextureTag->SetMaterial(sphereMaterial);
tempDoc->InsertMaterial(sphereMaterial.Release());
// allocate a BaseContainer for the texture baking settings and set a few meaningful values
BaseContainer textureBakingBC;
textureBakingBC.SetInt32(BAKE_TEX_WIDTH, 512);
textureBakingBC.SetInt32(BAKE_TEX_HEIGHT, 512);
textureBakingBC.SetBool(BAKE_TEX_COLOR, true);
// get the UVW tag from the sphere - it's not required to run GenerateUVW() to get the proper
// UVW representation because it's done internally by the InitBakeTexture
UVWTag* sphereUVWTag = (UVWTag *)polygonSphere->GetTag(Tuvw);
// proceed to bake the texture assigned in the color slot
BAKE_TEX_ERR initBakingRes = BAKE_TEX_ERR_NONE, bakingRes = BAKE_TEX_ERR_NONE;
// init the baking process
BaseDocument* bakingDoc = InitBakeTexture(tempDoc, sphereTextureTag, sphereUVWTag, NULL, textureBakingBC, &initBakingRes, NULL);
if (initBakingRes != BAKE_TEX_ERR_NONE)
{
GePrint("Failed to init texture baking[" + String::IntToString(initBakingRes) + "]");
BaseDocument::Free(bakingDoc);
return false;
}
// allocate the bitmap used for storing and saving the baking computations
AutoAlloc<BaseBitmap> bakingBmp;
if (!bakingBmp)
{
BaseDocument::Free(bakingDoc);
return false;
}
// execute the texture baking
bakingRes = BakeTexture(bakingDoc, textureBakingBC, bakingBmp, NULL, NULL, NULL);
if (bakingRes != BAKE_TEX_ERR_NONE)
{
GePrint("Failed to bake the texture[" + String::IntToString(bakingRes) + "]");
BaseDocument::Free(bakingDoc);
return false;
}
GePrint("Texture baking accomplished");
// free the baking document because we're still owning it
BaseDocument::Free(bakingDoc);
// save the bitmap on disk
Filename bakingBmpFilename("TextureBackingOutput.jpg");
Filename bakingBmpFullFilename = tempDoc->GetDocumentPath() + bakingBmpFilename;
IMAGERESULT bakingBmpRes = bakingBmp->Save(bakingBmpFullFilename, FILTER_JPG, nullptr, SAVEBIT_0);
if (bakingBmpRes != IMAGERESULT_OK)
{
GePrint("Failed to save baked texture bitmap [" + String::IntToString(bakingBmpRes) + "]");
return false;
}
GePrint("Texture baking saved on " + bakingBmpFullFilename.GetString());
break;
}
}
break;
}
}
return true;
}