Open Search
    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:126
    return OK
    Definition: apibase.h:2746
    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:1389
    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, const Char *maxonModuleID=MAXON_MODULE_ID)
    Definition: application.h:173
    Definition: basearray.h:415
    void Reset()
    Deletes all elements (calls destructors and frees memory).
    Definition: basearray.h:544
    static MAXON_METHOD Result< void > RegisterDatabaseWithUrl(const Id &databaseId, const Url &url, const CString &version=CString::DefaultValue())
    Definition: apibaseid.h:237
    Definition: url.h:942
    #define MAXON_INITIALIZATION(...)
    Definition: module.h:864
    @ CURRENT_MODULE_RESOURCE_DIR
    Resource directory of the module that invoked this call.
    #define iferr_scope_handler
    Definition: resultbase.h:1407
    #define iferr_return
    Definition: resultbase.h:1524

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

    Further Reading