Open Search
    ExchangeMapper Material Export Manual

    Introduction

    To export a custom Material definition (read ExchangeMapper Material Definition Manual), from your own custom Cinema 4D material, the next interfaces need to be implemented according to your need:

    One material can have multiple maxon::material::MaterialExportInterface or maxon::nodes::NodeMaterialExportInterface implementations describing how the export process will work.

    The export process provides automatic baking if a given material description is not handled by the maxon::material::MaterialExportInterface or maxon::nodes::NodeMaterialExportInterface implementations through the maxon::NODESPACE::EXCHANGE::BUNDLE::VIEWPORTMATERIAL material description.

    As an example, if an FBX is exported but the implemented exporter only handles a VIEWPORTMATERIAL material definition for the given material, the VIEWPORTMATERIAL material description provided by the exporter will be mapped to an FBX material description automatically.
    However, it's relevant to remind that this translation is a lossy translation, with data being sacrificed.
    For better handling, it's instead suggested to directly output an FBX material definition. For more information read ExchangeMapper Material Definition Manual.

    Note
    Within the material export implementation, it is recommended monitoring the thread cancellation state when executing time-consuming operations (e.g. baking) to react immediately upon user aborting an export process.

     MaterialExportInterface

    maxon::material::MaterialExportInterface can be called at any time, e.g. from a SceneLoaderData but also from a regular CommandData or anything else.

    maxon::material::MaterialExportInterface provides few methods:

    All MaterialExportInterface shall be registered using a maxon::material::MaterialExportDescription into the maxon::material::MaterialExporters registry.

    maxon::material::MaterialExportDescription links a given Classic API Plugin ID to a maxon::material::MaterialExportRef.

    Example of an implementation using the SimpleMaterial from the Cinema 4D SDK as the source of the export process.

    maxon::Result<void> SimpleMaterialExport::Initialize(const BaseMaterial& baseMaterial, const maxon::DataDictionary& config)
    {
    _baseMaterial = &baseMaterial;
    maxon::material::MaterialTypesMap materialTypes = config.Get(maxon::material::EXPORT::CONFIG::MATERIALTYPESWITHSUPPORT) iferr_return;
    // We only support Standard Surface in this example.
    CheckArgument(materialTypes.Contains(maxon::MATERIAL::PORTBUNDLE::STANDARDSURFACE::GetId()) == true);
    return maxon::OK;
    }
    {
    result.first = maxon::MATERIAL::PORTBUNDLE::STANDARDSURFACE::GetId();
    result.second = maxon::material::ParameterStorageInterface::LoadDefaults(maxon::MATERIAL::PORTBUNDLE::STANDARDSURFACE::GetId()) iferr_return;
    if (_baseMaterial != nullptr)
    {
    const Int32 SIMPLEMATERIAL_COLOR = 1000;
    const maxon::Color simpleMaterialColor = _baseMaterial->GetDataInstanceRef().GetVector(SIMPLEMATERIAL_COLOR).GetColor();
    maxon::material::ParameterStorageInterface::Insert(result.second, maxon::MATERIAL::PORTBUNDLE::STANDARDSURFACE::BASE_COLOR, simpleMaterialColor, true, 0) iferr_return;
    }
    return result;
    }
    maxon::Result<maxon::HashMap<maxon::Id, maxon::Data>> SimpleMaterialExport::GetTextures(const maxon::HashSet<maxon::Id>& texturedChannels)
    {
    // No textures to declare.
    return textures;
    }
    // The Registration Process
    static maxon::GenericData g_materialExportRegistration;
    maxon::Result<void> SimpleMaterialExport::Register()
    {
    const Int32 ID_SIMPLEMAT = 1001164;
    description._type = ID_SIMPLEMAT;
    description._class = SimpleMaterialExport::GetClass();
    g_materialExportRegistration = maxon::material::MaterialExporters::Register(SimpleMaterialExport::GetDescriptor().GetId(), std::move(description)) iferr_return;
    return maxon::OK;
    }
    void SimpleMaterialExport::Free()
    {
    g_materialExportRegistration = maxon::GenericData();
    }
    MAXON_COMPONENT_OBJECT_REGISTER(SimpleMaterialExport, "net.maxonsdk.doc_cpp.class.simplematerialexport");
    Definition: c4d_basematerial.h:28
    Definition: genericdata.h:20
    Definition: hashmap.h:1119
    MAXON_ATTRIBUTE_FORCE_INLINE Bool Contains(typename ByValueParam< KEYTYPE >::type key) const
    Definition: collection.h:1213
    Definition: tuple.h:611
    static Result< void > Insert(DataDictionary &parameters, KEY &&id, T &&value, Bool isConstant, UInt dynamicTimestamp)
    Definition: materialparameter.h:281
    static MAXON_METHOD Result< DataDictionary > LoadDefaults(const Id &materialType)
    PyObject PyObject * result
    Definition: abstract.h:43
    maxon::Int32 Int32
    Definition: ge_sys_math.h:60
    return OK
    Definition: apibase.h:2667
    #define CheckArgument(condition,...)
    Definition: errorbase.h:486
    #define MAXON_COMPONENT_OBJECT_REGISTER(C,...)
    Definition: objectbase.h:2473
    The maxon namespace contains all declarations of the MAXON API.
    Definition: autoweight.h:14
    #define iferr_scope
    Definition: resultbase.h:1374
    #define iferr_return
    Definition: resultbase.h:1465
    constexpr const Vec3< T, STRIDE > & GetVector() const
    Reinterprets the color as vector.
    Definition: col.h:388
    Definition: materialexport.h:155
    Class< MaterialExportRef > _class
    Definition: materialexport.h:157
    Int32 _type
    Definition: materialexport.h:156

     NodeMaterialExportInterface

    maxon::nodes::NodeMaterialExportInterface can be called at any time, e.g. from a SceneLoaderData but also from a regular CommandData or anything else.

    maxon::nodes::NodeMaterialExportInterface  provides few methods:

    To register a supported material definition, the maxon::nodes::NODESPACE::MATERIALEXCHANGEBUNDLEIDS attribute of the node space shall be filled with a maxon::BaseArray of material bundle maxon::Id.

    maxon::BaseArray<maxon::Id> materialExchangeBundleIds;
    materialExchangeBundleIds.Append(maxon::NODESPACE::EXCHANGE::BUNDLE::VIEWPORTMATERIAL::GetId()) iferr_return;
    nodeSpaceData.Set(maxon::nodes::NODESPACE::MATERIALEXCHANGEBUNDLEIDS, std::move(materialExchangeBundleIds)) iferr_return;
    MAXON_ATTRIBUTE_FORCE_INLINE ResultRef< T > Append(ARG &&x)
    Definition: basearray.h:677

    To register the custom exporter, the maxon::nodes::NODESPACE::MATERIALEXCHANGECLASS attribute of the node space shall be filled with the maxon::nodes::NodeMaterialExportInterface maxon::Class object.

    // nodeSpaceData.Set(maxon::nodes::NODESPACE::MATERIALEXCHANGECLASS, YourMaterialNodeExportInterfaceImplementation::GetClass()) iferr_return;

    If no exporter is defined for a given node space, a fall-back is performed by the maxon::nodes::MaterialExchangeInterface to create a textured material of type maxon::NODESPACE::EXCHANGE::BUNDLE::VIEWPORTMATERIAL.

    Further Reading