THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 12/11/2009 at 11:43, xxxxxxxx wrote:
I'd do it this way. Note the allocation checks, checks for existence, and the check for 'doc' before doc->StartUndo(). Also, not sure if this is your intention, but once you remove the objects from the document, if they are no longer necessary, you still need to free them - otherwise subsequent allocations into those pointers will leave unfreed/unreferenced objects in memory!
Unfortunately, this is one reason that I don't have a great love of C/C++ - the programmer takes control of all memory management as well as tracking pointer validation.
/////////////////////////////////////////////////////////////
// Planet
#include "c4d.h"
#include "c4d_symbols.h"
#include "oplanet.h"
#include "c4d_basetag.h"
#include "c4d_basematerial.h"
// be sure to use a unique ID obtained from www.plugincafe.com
#define ID_PLANET_OBJECT 1024532
class Planet : public ObjectData
{
public:
virtual Bool Init(GeListNode *node);
virtual Bool GetDEnabling(GeListNode *node, const DescID &id;,GeData &t;_data,LONG flags,const BaseContainer *itemdesc);
virtual Bool Message(GeListNode *node, LONG type, void *t_data);
Bool CreatePlanet(DescriptionCommand* dc, BaseObject* op);
Bool UpdatePlanet(DescriptionCommand* dc, BaseObject* op);
static NodeData *Alloc(void) { return gNew Planet;}
TextureTag* surfaceTextTag;
TextureTag* cloudsTextTag;
TextureTag* atmTextTag;
BaseObject* surface;
Material* surfaceMat;
BaseObject* clouds;
Material* cloudsMat;
BaseObject* atmosphere;
Material* atmosphereMat;
Bool planetCreated;
LONG test;
};
// initialize settings
Bool Planet::Init(GeListNode *node)
{
//Called when a new instance of the node plugin has been allocated. You can use this function to for example fill the BaseContainer of the connected node with default values:
BaseContainer* bc = ((BaseObject* )node)->GetDataInstance();
if (!bc) return false;
bc->SetBool(ENABLE_CRATERS, TRUE);
bc->SetBool(ENABLE_ATMOSPHERE, TRUE);
bc->SetBool(HAS_RINGS, FALSE);
planetCreated = FALSE;
test = 0;
return TRUE;
}
Bool Planet::GetDEnabling(GeListNode *node, const DescID &id;,GeData &t;_data,LONG flags,const BaseContainer *itemdesc)
{
// Enable/disable our parameters
BaseContainer *bc=((BaseList2D* )node)->GetDataInstance();
BaseObject* op = static_cast<BaseTag*>(node)->GetObject();
if (!op) return FALSE;
switch (id[0].id)
{
case SURFACE_PRESETS:
return bc->GetBool(USE_PRESET);
case CRATER_AMOUNT:
if (bc->GetBool(ENABLE_CRATERS)&&!bc->GetBool(USE_PRESET)) return TRUE;
case CRATER_SIZE:
if (bc->GetBool(ENABLE_CRATERS)&&!bc->GetBool(USE_PRESET)) return TRUE;
case SURFACE_MAP:
return !bc->GetBool(USE_PRESET);
case ELEVATION_MAP:
return !bc->GetBool(USE_PRESET);
case ELEVATION_STRENGTH:
return !bc->GetBool(USE_PRESET);
case ENABLE_CRATERS:
return !bc->GetBool(USE_PRESET);
case CLOUD_MAP:
return !bc->GetBool(USE_PRESET2);
case CLOUD_BRIGHTNESS:
return !bc->GetBool(USE_PRESET2);
case CLOUD_THICKNESS:
return !bc->GetBool(USE_PRESET2);
case CLOUD_PRESETS:
return bc->GetBool(USE_PRESET2);
case ATMOSPHERIC_COLOR:
return bc->GetBool(ENABLE_ATMOSPHERE);
case ATMOSPHERIC_BRIGHTNESS:
return bc->GetBool(ENABLE_ATMOSPHERE);
case ATMOSPHERIC_GLOW:
return bc->GetBool(ENABLE_ATMOSPHERE);
case RING_COLOR:
return bc->GetBool(HAS_RINGS);
case CREATE_PLANET:
return !planetCreated;
}
return TRUE;
}
Bool Planet::Message(GeListNode *node, LONG type, void *t_data)
{
if (!node) return FALSE;
if (type == MSG_DESCRIPTION_COMMAND)
return CreatePlanet(static_cast<DescriptionCommand*>(t_data), static_cast<BaseObject*>(node));
if (type == MSG_DESCRIPTION_CHECKUPDATE)
return UpdatePlanet(static_cast<DescriptionCommand*>(t_data), static_cast<BaseObject*>(node));
return TRUE;
}
Bool Planet::CreatePlanet(DescriptionCommand* dc, BaseObject* op)
{
if (!dc) return TRUE;
if (!op) return FALSE;
LONG id = dc->id[0].id;
//declarations
surfaceTextTag = TextureTag::Alloc();
if (!surfaceTextTag) return FALSE;
cloudsTextTag = TextureTag::Alloc();
if (!cloudsTextTag) return FALSE;
atmTextTag = TextureTag::Alloc();
if (!atmTextTag) return FALSE;
atmosphere = BaseObject::Alloc(Osphere);
if (!atmosphere) return FALSE;
atmosphereMat = Material::Alloc();
if (!atmosphereMat) return FALSE;
clouds = BaseObject::Alloc(Osphere);
if (!clouds) return FALSE;
cloudsMat = Material::Alloc();
if (!cloudsMat) return FALSE;
surface = BaseObject::Alloc(Osphere);
if (!surface) return FALSE;
surfaceMat = Material::Alloc();
if (!surfaceMat) return FALSE;
BaseDocument* doc = op->GetDocument();
if (!doc) return FALSE;
doc->StartUndo();
BaseObject* prnt = doc->GetActiveObject();
BaseTag* tp = BaseTag::Alloc(Tphong);
if (!tp) return FALSE;
//If Create Planet button is pressed...
if (id == CREATE_PLANET)
{
/////////create the atmosphere sphere//////////////////////////////////////////////////////
atmosphere->SetName("Atmosphere");
atmosphereMat->SetName ("Atmosphere");
atmosphere->SetParameter(PRIM_SPHERE_RAD,200.8,NULL);
/////////create and insert the clouds sphere///////////////////////////////////////////////
clouds->SetName("Clouds");
cloudsMat->SetName ("Clouds");
clouds->SetParameter(PRIM_SPHERE_RAD,200.4,NULL);
clouds->InsertTag(tp,0);//phong tag
clouds->InsertTag(cloudsTextTag,0);
cloudsTextTag->SetMaterial(cloudsMat);
doc->InsertMaterial(cloudsMat,NULL,TRUE);
if (clouds) doc->InsertObject(clouds, prnt, NULL, FALSE);
GePrint("Clouds Created");
/////////create and insert the surface sphere///////////////////////////////////////////////
surface->SetName("Surface");
surfaceMat->SetName ("Surface");
surface->SetParameter(PRIM_SPHERE_RAD,200,NULL);
surface->InsertTag(tp,0);//phong tag
surface->InsertTag(surfaceTextTag,0);
surfaceTextTag->SetMaterial(surfaceMat);
doc->InsertMaterial(surfaceMat,NULL,TRUE);
if (surface) doc->InsertObject(surface, prnt, NULL, FALSE);
GePrint("Surface Created");
//A planet was created
planetCreated = TRUE;
doc->EndUndo();
}
return TRUE;
}
Bool Planet::UpdatePlanet(DescriptionCommand* dc, BaseObject* op)
{
if (!dc) return TRUE;
if (!op) return FALSE;
BaseDocument* doc = op->GetDocument();
if (!doc) return FALSE;
doc->StartUndo();
BaseObject* prnt = doc->GetActiveObject();
BaseTag* tp = BaseTag::Alloc(Tphong);
if (!tp) return FALSE;
//Enable-Disable Atmosphere/////////////////////////////////////////////////////////
if (op->GetDataInstance()->GetBool(ENABLE_ATMOSPHERE)==TRUE)
{
if (atmTextTag)
{
if (atmosphere) atmosphere->InsertTag(atmTextTag,0);
atmTextTag->SetMaterial(atmosphereMat);
}
if (atmosphereMat)
{
doc->InsertMaterial(atmosphereMat,NULL,TRUE);
atmosphereMat->SetChannelState(CHANNEL_TRANSPARENCY,TRUE);
atmosphereMat->SetChannelState(CHANNEL_GLOW,TRUE);
atmosphereMat->Update(TRUE,TRUE);
}
if (atmosphere)
{
atmosphere->InsertTag(tp,0); //phong tag
doc->InsertObject(atmosphere, prnt, NULL, FALSE);
}
GePrint("Atmosphere Created");
GePrint("Atmosphere Enabled");
}
else
{
if (atmosphere) atmosphere->Remove();
if (atmosphereMat)
{
atmosphereMat->SetChannelState(CHANNEL_GLOW,FALSE);
GePrint("Atmosphere Disabled");
atmosphereMat->Remove();
}
if (atmTextTag) atmTextTag->Remove();
}
/////////////////////////////////////////////////////////////////////////////////////
if (atmosphereMat) atmosphereMat->SetParameter(MATERIAL_GLOW_OUTERSTRENGTH,op->GetDataInstance()->GetReal(ATMOSPHERIC_BRIGHTNESS),NULL);
return TRUE;
}
Bool RegisterPlanet(void)
{
// decide by name if the plugin shall be registered - just for user convenience
GePrint("-----------------------------------------------------------------------------------------");
GePrint("Planet X Generator 1.0 - Copyright 2009 - Shawn Foster");
GePrint("-----------------------------------------------------------------------------------------");
String name=GeLoadString(IDS_PLANET_OBJECT); if (!name.Content()) return TRUE;
return RegisterObjectPlugin(ID_PLANET_OBJECT,name,OBJECT_GENERATOR|OBJECT_INPUT,Planet::Alloc,"oplanet","Planet.tif",0);
}