Using extensions from plugins or external programs

When filling a scene with objects, extension objects can be created with or without being installed in the system. But, obviously, to render a scene with extension objects they must be installed.

Working with installed extensions

In order to use extensions the first step is knowing which ones are installed. This can be done with the following code snippet:

CextensionManager* extensionManager = CextensionManager::instance();
char* plugsPath = "C:\\Maxwell\\extensions";
extensionManager->setExtensionsDirectory( plugsPath );
extensionManager->loadAllExtensions();

dword numGeometryModifierExtensions = extensionManager->getGeometryModifierExtensionsCount();
for( dword i = 0; i < numGeometryModifierExtensions; i++ )
{
	const char* extensionName = extensionManager->getGeometryModifierExtensionAtIndex( i )->getName();
	fprintf( stderr, "\t\t%s\n", extensionName );
} 
 
dword numGeometryLoaderExtensions = extensionManager->getGeometryLoaderExtensionsCount();
for( dword i = 0; i < numGeometryLoaderExtensions; i++ )
{
	const char* extensionName = extensionManager->getGeometryLoaderExtensionAtIndex( i )->getName();
	fprintf( stderr, "\t\t%s\n", extensionName );
} 

dword numProceduralGeometryExtensions = extensionManager->getGeometryProceduralExtensionsCount();
for( dword i = 0; i < numProceduralGeometryExtensions; i++ )
{
	const char* extensionName = extensionManager->getGeometryProceduralExtensionAtIndex( i )->getName();
	fprintf( stderr, "\t\t%s\n", extensionName );
}

dword numMaterialModifierExtensions = extensionManager->getMaterialModifierExtensionsCount();
for( dword i = 0; i < numSceneModifierExtensions; i++ )
{
	const char* extensionName = extensionManager->getMaterialModifierExtensionAtIndex( i )->getName();
	fprintf( stderr, "\t\t%s\n", extensionName );
}

dword numTextureExtensions = extensionManager->getTextureExtensionsCount();
for( dword i = 0; i < numProceduralGeometryExtensions; i++ )
{
	const char* extensionName = extensionManager->getTextureExtensionAtIndex( i )->getName();
	fprintf( stderr, "\t\t%s\n", extensionName );
}

dword numCameraLensExtensions = extensionManager->getCameraLensExtensionsCount();
for( dword i = 0; i < numCameraLensExtensions ; i++ )
{
	const char* extensionName = extensionManager->getSceneModifierExtensionAtIndex( i )->getName();
	fprintf( stderr, "\t\t%s\n", extensionName );
}

dword numSceneModifierExtensions = extensionManager->getSceneModifierExtensionsCount();
for( dword i = 0; i < numSceneModifierExtensions; i++ )
{
	const char* extensionName = extensionManager->getSceneModifierExtensionAtIndex( i )->getName();
	fprintf( stderr, "\t\t%s\n", extensionName );
} 

dword numSkyExtensions = extensionManager->getSkyExtensionsCount();
for( dword i = 0; i < numSceneModifierExtensions; i++ )
{
	const char* extensionName = extensionManager->getSkyExtensionAtIndex( i )->getName();
	fprintf( stderr, "\t\t%s\n", extensionName );
} 

 

Once we know which extensions are installed, we can create and fill the desired extension instance data container. For example, assume there is a geometry loader extension called "CubeExtension", with one parameter called "CubeSize" of type float:

Cmaxwell* scene = new Cmaxwell( pCallBack );
CextensionManager* extensionManager = CextensionManager::instance();
CgeometryLoaderExtension* geomLoadExtension = extensionManager->createGeometryLoaderExtension( "CubeExtension" );
if( geomLoadExtension == NULL )//Always check
{
	return;
}
MXparamList* cubeParams = geomLoadExtension->getExtensionData();
if( cubeParams == NULL )//Check again. It should not happen, tho...
{
	return;
}
//Now we fill the data container.
float cubeSize = 17.3f;
cubeParams->setFloat( "CubeSize", cubeSize );

//Once filled, create the extension object in the scene and we´re done.
Cmaxwell::Cobject obj = scene->createGeometryLoaderObject( "MyCube", cubeParams );
//Now we can assign a material, set its position, scale, rotation like any object
.....
//Once we're done, free the temporary plugin used for assigning. 
delete geomLoadExtension;

 

For example, let's create a checker texture and assign it to the reflectance 0º color of a material:

Cmaxwell* mw = new Cmaxwell( pCallBack );
CtextureExtension* textureExtension = plugMan->createDefaultTextureExtension( "Checker" );
Cmaxwell::Cobject obj;
MXparamList* plist = textureExtension->getExtensionData();

//Set some parameters
plist->setByte("disable_blending", 0);
plist->setFloat("Blend procedural", 1.0);

plist->setByte("Number of elements U", 3);
plist->setByte("Number of elements V", 5);

Cmaxwell::Cmaterial material = mw->createMaterial( "myMaterial", true );
Cmaxwell::CmaterialLayer layer = material.addLayer ();
Cmaxwell::Cbsdf bsdf = layer.addBSDF();
Cmaxwell::Creflectance reflectance = bsdf.getReflectance();

// Set the reflectance as a texture
Cmaxwell::Cattribute attr;
attr.activeType = maxwellrender::MAP_TYPE_BITMAP;
attr.textureMap.addProceduralTexture( plist );
reflectance.setAttribute( "color", attr );
.......

 

Working with not installed extensions

When the extensions are not installed, all we have to do is fill a generic data container with all the required parameters for the extension to work and create the corresponding type of extension object in the scene. We must know several things about the extension to use: name, parameter names and types. With these items we will fill the extension data container, and continue like the above case. It is important to fill all parameters.

Cmaxwell* scene = new Cmaxwell( pCallBack ); 
MXparamList* extParams = new MXparamList( "CubeExtension" );

//Now we fill the data container. 
float cubeSize = 17.3f; 
extParams->setFloat( "CubeSize", cubeSize );

//Once filled, create the extension object as in the previous case
Cmaxwell::Cobject obj = scene->createGeometryLoaderObject( "MyCube", extParams ); 
.....
//Once we're done, free the container.
delete extParams;