Core Nodes Implementation

About

A core node is a basic node of Cinema 4D's node material system. It represents a basic functionality that can be used in a node material.

The relevant interfaces needed to implement custom core nodes are found in the corenodes.framework.

Implementation

A simple custom core node is implemented as follows:

// This example shows
// core node class
class MaximumComponentCoreNode
{
public:
// input port "colora"
// input port "colorb"
// output port "result"
{
public:
MAXON_ATTRIBUTE_FORCE_INLINE maxon::Result<void> Process(const Ports<colora, colorb, result>& ports) const
{
// access input port color
const maxon::ColorA& inputColorA = ports.colora();
const maxon::ColorA& inputColorB = ports.colorb();
// invert color
maxon::ColorA resultColor;
resultColor.r = maxon::Max(inputColorA.r, inputColorB.r);
resultColor.g = maxon::Max(inputColorA.g, inputColorB.g);
resultColor.b = maxon::Max(inputColorA.b, inputColorB.b);
resultColor.a = maxon::Max(inputColorA.a, inputColorB.a);
// store in result port
ports.result.Update(resultColor);
return maxon::OK;
}
};
static maxon::Result<void> Init(const maxon::corenodes::MicroNodeGroupRef& group)
{
return group.AddChild<Impl>();
}
};
using namespace maxon::corenodes;
// we choose pure registration, because the node has no lazy evaluation (and is evaluated from left to right).
MAXON_CORENODE_REGISTER_PURE(MaximumComponentCoreNode, "net.maxonexample.corenodes.examplenode");
Definition: micronodes.h:208
#define MAXON_CORENODE_REGISTER_PURE(CLS, id,...)
Definition: corenodes.h:1034
PyObject PyObject * result
Definition: abstract.h:43
#define MAXON_ATTRIBUTE_FORCE_INLINE
Definition: apibase.h:111
return OK
Definition: apibase.h:2690
constexpr MAXON_ATTRIBUTE_FORCE_INLINE X Max(X a, X b)
Calculates the maximum of two values and return it.
Definition: apibasemath.h:349
#define MAXON_PORT_OUTPUT(T, name,...)
Definition: micronodes_ports.h:223
#define MAXON_PORT_INPUT(T, name,...)
Definition: micronodes_ports.h:61
This namespace contains the API of the nodes framework.
Definition: corenodes.h:10
#define iferr_scope
Definition: resultbase.h:1384
A color consisting of three components R, G, B and an alpha.
Definition: col4.h:16
T r
Definition: col4.h:35
T g
Definition: col4.h:36
T a
Definition: col4.h:38
T b
Definition: col4.h:37

Description

The description of the core node must be created with the Resource Editor.The new data type must have the ID of the core node.

The data type properties are:

  • Classification: "node"
  • Description Processor: "CoreNodeDescriptionProcessor"
  • Processor Parameters: The core node ID.
  • Menu Category: Select a category for the node.

The core node needs a new attribute:

  • Command: "include"
  • Identifier: "net.maxon.node.base"
  • Include: "net.maxon.node.base"

The name of the node is set with net.maxon.node.base.

Port descriptions are created with new attributes:

  • Command: "attribute"
  • Identifier: the port ID
  • Datatype: The port data type
  • Classification: "input" or "output"
  • Gui Type Id: The proper UI for that data type
  • Group Id: The proper group, either "net.maxon.node.base.group.inputs" or "net.maxon.node.base.group.outputs"
  • String: The name displayed in the UI.

Description Handling

The description of the core node must be loaded and handled properly:

// This example loads and handles the description database containing the core node description.
static maxon::BaseArray<maxon::GenericData> g_coreNodeDescriptions;
// the ID of the database storing the core node's description
static maxon::Id g_corenodesDatabaseId = maxon::Id { "net.maxonexample.corenodes" };
// function to process the description
// static maxon::Result<void> HandleCoreNodeDescriptions(const maxon::Id& databaseId)
//{
// iferr_scope;
//
// const maxon::Id catData = maxon::DATADESCRIPTION_CATEGORY_DATA;
// const maxon::LanguageRef language = maxon::LanguageRef();
//
// maxon::BaseArray<maxon::IdAndVersion> ids = maxon::DataDescriptionDefinitionDatabaseInterface::GetRegisteredDescriptions(g_corenodesDatabaseId, catData, language) iferr_return;
// for (const maxon::IdAndVersion& id : ids)
// {
// maxon::DataDescription description = maxon::DataDescriptionDatabaseInterface::LoadDescription(maxon::DATADESCRIPTION_CATEGORY_DATA, maxon::LanguageRef(), id.first) iferr_return;
//
// maxon::DataDictionary info = description.GetInfo();
//
// maxon::Id builderId = info.Get(maxon::DESCRIPTION::DATA::INFO::PROCESSOR, maxon::Id());
// if (builderId.IsPopulated())
// {
// const maxon::DescriptionProcessor& processor = maxon::DescriptionProcessors::Get(builderId);
// if (processor)
// {
// maxon::GenericData d = processor.Process(id.first, description) iferr_return;
// g_coreNodeDescriptions.Append(std::move(d)) iferr_return;
// }
// }
// }
//
// return maxon::OK;
//}
// load description
static maxon::Result<void> HandleInitializeModule()
{
{
err.CritStop();
return err;
};
// get plugin "res" folder
// get "nodes" folder within the "res" folder
const maxon::Url coreNodesResourceUrl = pluginDir.Append("nodes"_s) iferr_return;
// register database
// handle the core node description
//HandleCoreNodeDescriptions(g_corenodesDatabaseId) iferr_return; // commented out due to duplication in DB registration occurred because of the line above
return maxon::OK;
}
// free description
static void HandleFreeModule()
{
g_coreNodeDescriptions.Reset();
}
MAXON_INITIALIZATION(HandleInitializeModule, HandleFreeModule);
static MAXON_FUNCTION Result< Url > GetUrl(APPLICATION_URLTYPE urlType)
Definition: basearray.h:412
void Reset()
Deletes all elements (calls destructors and frees memory).
Definition: basearray.h:541
static MAXON_METHOD Result< void > RegisterDatabaseWithUrl(const Id &databaseId, const Url &url, const CString &version=CString::NullValue())
Definition: apibaseid.h:253
Definition: url.h:952
#define MAXON_INITIALIZATION(...)
Definition: module.h:795
@ CURRENT_MODULE_RESOURCE_DIR
Resource directory of the module that invoked this call.
#define iferr_scope_handler
Definition: resultbase.h:1402
#define iferr_return
Definition: resultbase.h:1519

This is an extended version of the typical procedure to load MAXON API descriptions. See Loading Data Descriptions.

Further Reading