描述 Manual
A 描述 object stores information on how C4DAtom parameters are to be displayed in the GUI (Attribute Manager). It contains information on:
The information is stored using description setting IDs, see Description Settings Manual .
To add dynamic parameters to a NodeData based plugin one can implement NodeData::GetDDescription() . This function receives a given 描述 object that should be filled with the description of the visible parameters.
见 NodeData::GetDDescription() Manual .
// This example defines the element's parameter description by loading the registered description of the plugin type.// load the description of this type if (description-> LoadDescription (node-> GetType ()) == false ) return false ; flags |= DESCFLAGS_DESC::LOADED ; return SUPER::GetDDescription(node, description, flags); }
Correspondingly it is possible to get the parameter description from a C4DAtom :
见 C4DAtom Parameter Properties .
// This example prints the names of all parameters in the current parameter description. AutoAlloc<Description> description; if (description == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );// get the Description of the given object if (!object-> GetDescription (description, DESCFLAGS_DESC::NONE )) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION ); void * handle = description-> BrowseInit (); const BaseContainer * bc = nullptr ; DescID id, gid;
// loop through all elements of the description while (description-> GetNext (handle, &bc, id , gid)) { ApplicationOutput ( "Parameter Name: " + bc-> GetString ( DESC_NAME )); } description-> BrowseFree (handle);
A 描述 object can be created with the usual tools:
This is needed to access the parameter description of a given object:
// This example accesses the Description of the given object.// check if an object is selected BaseObject * const activeObject = doc-> GetActiveObject (); if (activeObject == nullptr ) return maxon::IllegalArgumentError( MAXON_SOURCE_LOCATION );
// check if the Description object could be allocated AutoAlloc<Description> description; if (description == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );
// read the Description from the active object if (activeObject-> GetDescription (description, DESCFLAGS_DESC::NONE )) { ApplicationOutput ( "Got Description" ); }
The description of an plugin's static parameters is defined in the plugin's *.res file. This *.res file is typically registered using the "Register" function of the plugin (see 一般插件信息手册 ). Such a registered description can then be loaded:
A custom data type can also define its own description. This sub-description (or sub-channels) can be loaded with:
// load parameter sub-description AutoAlloc<AtomArray> elements; if (elements == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION ); elements-> Append (sweepObj); AutoAlloc<Description> desc; if (desc == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );
// get plugin structure for the given resource plugin RESOURCEDATATYPEPLUGIN* resDataType = FindResourceDataTypePlugin (completeID[-1].dtype); if (resDataType == nullptr ) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION );
// load sub-description const Bool gotSubDescription = desc-> GetSubDescriptionWithData ( completeID, elements, resDataType, BaseContainer (), nullptr ); if (!gotSubDescription) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION );
// print names of sub-description parameters
void * handle = desc-> BrowseInit (); const BaseContainer * bc = nullptr ; DescID loopID, gid;// loop through sub-description parameters while (desc-> GetNext (handle, &bc, loopID, gid)) ApplicationOutput (bc-> GetString ( DESC_NAME )); desc-> BrowseFree (handle);
In certain situations NodeData::GetDDescription() is not called to get the description of all parameters but of only one specific parameter.
Existing parameter descriptions are stored in BaseContainers that can be accessed with:
// parameter ID DescID cid = DescLevel (EXAMPLE_GENERATOR_BUTTON, DTYPE_BUTTON , 0);
// check if this parameter ID is requested if (singleid == nullptr || cid. IsPartOf (*singleid, nullptr )) { BaseContainer * settings = nullptr ; settings = description-> GetParameterI (cid, nullptr ); if (settings) settings-> SetString ( DESC_SHORT_NAME , "New Button Name" _s); }
Also a new parameter description can be added:
// add a parameter description DescID cid = DescLevel (1003, DTYPE_REAL , 0);
// check if this parameter ID is requested (NOTE: this check is important for speed) if (singleid == nullptr || cid. IsPartOf (*singleid, nullptr )) { // define the new parameter description BaseContainer settings = GetCustomDataTypeDefault ( DTYPE_REAL ); 设置。 SetString ( DESC_NAME , "A new parameter" _s);
// set the new parameter if (!description-> SetParameter (cid, settings, ID_OBJECTPROPERTIES )) return ; }
There are two ways to iterate over all elements stored in a 描述 object. The first way is to loop over all stored parameters in a list:
// load the Description of the material preview element if (tempDesc && tempDesc-> LoadDescription ( "Mpreview" )) { void * handle = tempDesc-> BrowseInit (); const BaseContainer * settings = nullptr ; DescID id, gid;
// loop through the elements of the description while (tempDesc-> GetNext (handle, &settings, id , gid)) { description-> SetParameter ( id , *settings, gid); } tempDesc-> BrowseFree (handle); }
The other way to iterate over all elements is to navigate down the tree hierarchy defined by parameter groups:
// read the Description from the active object if (!object-> GetDescription (description, DESCFLAGS_DESC::NONE )) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION );
// loop through description // get the first element AutoAlloc<AtomArray> ar; if (ar == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION ); DescEntry* entry = description-> GetFirst (ar); while (entry != nullptr ) { // get element const BaseContainer * bc = nullptr ; DescID descid; description-> GetDescEntry (entry, &bc, descid);
// print description name if (bc != nullptr ) ApplicationOutput (bc-> GetString ( DESC_NAME ));
// handle sub-entries (elements of parameter groups etc.) // HandleSubEntries() is a custom function DescEntry* const subEntries = description-> GetDown (entry); HandleSubEntries(subEntries); entry = description-> GetNext (entry); }
This convenience function allows to fill the BaseContainer for a pop-up menu based on the content of the 描述 :
This function allows to complete a given DescID :
// check if the ID exists and complete it if (description-> CheckDescID (incompleteID, arr, &completeID)) { // check if the completed ID describes a float parameter if (completeID[-1].dtype == DTYPE_REAL ) ApplicationOutput ( "This is a float parameter" ); }