Introduction
To import a custom Material definition (read ExchangeMapper Material Definition Mapper Manual), into your own custom Cinema 4D material, the next interfaces should be implemented according to the specific needs:
One material definition can have multiple maxon::material::MaterialImportInterface or maxon::nodes::NodeMaterialImportInterface implementations describing how the import process takes place.
It is up to the requirements to create the material definition and import the data to choose which MaterialImportRef/MaterialNodeImportRef will perform the material creation.
It is also possible to create multiple material types by using multiples MaterialImportRef/MaterialNodeImportRef.
The import process does not provide an automatic baking functionality if a given material description is not handled by the maxon::material::MaterialImportInterface or maxon::nodes::NodeMaterialImportInterface implementations.
This ensures that, the 3-rd party developer should carefully considers what an unknown material description could mean for his material type since he should know and, probably, generate the default values.
However, one may be interested to explicitly convert the given material description to another one that he already knows. For more information read ExchangeMapper Material Definition Mapper Manual.
MaterialImportInterface
A maxon::material::MaterialImportInterface can be called at any time: from a SceneLoaderData but also from a regular CommandData or anything else.
A maxon::material::MaterialImportInterface provides a CreateMaterial() methods that need to be implemented.
It's important to registers the maxon::Class object representing the current maxon::material::MaterialImportInterface implementation into the maxon::material::MaterialImporters registry. Because of this, a SceneLoaderData can expose to the user all possible import solutions available. The following code is an implementation example:
{
importDescription.
_class = SimpleMaterialImport::GetClass();
g_materialImportRegistration = maxon::material::MaterialImporters::Register(SimpleMaterialImport::GetDescriptor().GetId(), std::move(importDescription))
iferr_return;
}
void SimpleMaterialImport::Free()
{
}
Definition: genericdata.h:20
return OK
Definition: apibase.h:2667
String LoadResourceString(const STRID &identifier, const ARGUMENTS &... args)
Loads the string 'identifier' from the resource and format with the passed parameters.
Definition: string.h:2187
#define MAXON_COMPONENT_OBJECT_REGISTER(C,...)
Definition: objectbase.h:2473
#define iferr_scope
Definition: resultbase.h:1374
#define iferr_return
Definition: resultbase.h:1465
Definition: materialimport.h:99
String _name
Definition: materialimport.h:100
Class< MaterialImportRef > _class
Definition: materialimport.h:101
The maxon::material::MaterialImportInterface::CreateMaterial() returns a pointer to a BaseMaterial.
The ownership of this BaseMaterial should be properly managed: whilst it's up to the maxon::material::MaterialImportInterface to allocate the BaseMaterial, the importer is responsible to insert it into the document (and transfer the ownership to it) or either to free the allocated BaseMaterial.
This method is called during the import process with the material definition (maxon::material::MaterialExchangeData) and only for context purpose, the BaseDocument the BaseMaterial should be created into and a maxon::DataDictionary containing the import configuration.
The following code is an implementation using the SimpleMaterial from Cinema 4D SDK as the target of the import process.
{
const Int32 ID_SIMPLEMAT = 1001164;
const Int32 SIMPLEMATERIAL_COLOR = 1000;
if (materialData._materialTypeId ==
maxon::
MATERIAL::PORTBUNDLE::STANDARDSURFACE::GetId())
{
simpleMaterialColor = baseColor.
_value.GetVector();
}
else if (materialData.
_materialTypeId == maxon::MATERIAL::PORTBUNDLE::FBXSURFACELAMBERT::GetId() || materialData.
_materialTypeId == maxon::MATERIAL::PORTBUNDLE::FBXSURFACEPHONG::GetId())
{
simpleMaterialColor = diffuse.
_value.GetVector();
}
else
{
maxon::Id targetMaterialDefinition = maxon::MATERIAL::PORTBUNDLE::STANDARDSURFACE::GetId();
{
if (
mapping._source != srcMaterialDefinition)
continue;
if (
mapping._target != targetMaterialDefinition)
continue;
unknowToStandardMappingDescription =
mapping;
break;
}
if (unknowToStandardMappingDescription.
_source == srcMaterialDefinition && unknowToStandardMappingDescription.
_target == targetMaterialDefinition)
{
maxon::material::MaterialMappingRef unknowToStandardMapping = unknowToStandardMappingDescription.
_class.Create()
iferr_return;
}
}
return simpleMaterial;
}
BasePlugin * FindPlugin(Int32 id, PLUGINTYPE type)
Vector GetVector(Int32 id, const Vector &preset=Vector()) const
Definition: c4d_basecontainer.h:371
void SetVector(Int32 id, const Vector &v)
Definition: c4d_basecontainer.h:555
Definition: c4d_basedocument.h:498
const BaseContainer & GetDataInstanceRef() const
Definition: c4d_baselist.h:2344
static BaseList2D * Alloc(Int32 type)
Definition: c4d_basematerial.h:28
The base class for Cinema 4D plugins.
Definition: c4d_baseplugin.h:70
Definition: apibaseid.h:253
static MAXON_METHOD Result< DataDictionary > LoadDefaults(const Id &materialType)
Py_ssize_t PyObject * mapping
Definition: unicodeobject.h:919
maxon::Int32 Int32
Definition: ge_sys_math.h:60
@ MATERIAL
3D shader. (MaterialData)
#define CheckState(condition,...)
Definition: errorbase.h:510
BaseMaterial * CreateMaterial(BaseList2D *const asset, Int32 graphIndex, SUBSTANCE_MATERIAL_MODE mode)
MATERIAL
Material mode.
Definition: lib_activeobjectmanager.h:4
The maxon namespace contains all declarations of the MAXON API.
Definition: autoweight.h:14
Definition: materialparameter.h:113
DataDictionary _parameters
Definition: materialparameter.h:132
Id _materialTypeId
Definition: materialparameter.h:125
HashMap< Id, Data > _textures
Definition: materialparameter.h:141
Definition: materialmapping.h:119
Id _source
Definition: materialmapping.h:120
Id _target
Definition: materialmapping.h:121
Class< MaterialMappingRef > _class
Definition: materialmapping.h:122
Definition: materialparameter.h:186
TYPE _value
Definition: materialparameter.h:201
NodeMaterialImportInterface
A maxon::nodes::NodeMaterialImportInterface can be called at any time, e.g. from a SceneLoaderData but also from a regular CommandData or anything else.
A maxon::nodes::NodeMaterialImportInterface provides an Import method that needs to be implemented.
This method is called during the import process with a node graph to be filled (NodesGraphModelRef) with the material definition (maxon::material::MaterialExchangeData) and only for context purpose, the document. It's up to the importer to decide what to do:
- it can read attribute values directly from the material description and fed the data directly within the end node of the graph or
- it can create an "import" node that represents the material description, then link the value from this "import" node to the end node of the graph to have the raw data exposed to the user.
To help in the process of the "import" node the maxon::nodes::NodeMaterialImportHelperInterface can be used to creates attributes that will be exposed as a node in the node graph.
{
{
for (const auto& textureEntry : textureReferences)
{
const maxon::Id& textureId = textureEntry.GetKey();
const maxon::Data& textureData = textureEntry.GetValue();
if (textureType == maxon::GetDataType<maxon::material::ImageReference>())
{
}
else if (textureType == maxon::GetDataType<maxon::material::SubstanceReference>())
{
}
else
{
DiagnosticOutput(
"Parameter '@' has texture reference of unknown type '@'.", textureId, textureType);
}
}
}
{
helper.AddParameters(materialData._parameters)
iferr_return;
const
maxon::nodes::NodeMaterialImportHelperInterface::GroupNodeData groupData = helper.Finalize()
iferr_return;
}
}
{
if (substances == nullptr)
return nullptr;
const Bool onlySelected =
false;
{
if (asset == nullptr)
continue;
return asset;
}
return nullptr;
}
#define Import(a0, a1, a2, a3, a4, a5)
Definition: Python-ast.h:536
Definition: ge_autoptr.h:37
Definition: c4d_baselist.h:2190
String GetName() const
Definition: c4d_baselist.h:2363
Definition: c4d_string.h:39
Definition: datatypebase.h:1199
Result< typename std::conditional< GetCollectionKind< T >::value==COLLECTION_KIND::ARRAY, T, typename ByValueParam< T >::type >::type > Get() const
Definition: datatypebase.h:1404
const DataType & GetType() const
Definition: datatypebase.h:1272
Definition: datatypebase.h:772
static MAXON_METHOD Result< NodeMaterialImportHelperRef > CreateAndInitialize(NodesGraphModelRef &graph, const Id &materialType)
Py_ssize_t * index
Definition: abstract.h:374
OK
Ok.
Definition: ge_prepass.h:0
maxon::Bool Bool
Definition: ge_sys_math.h:55
#define MAXON_SCOPE
Definition: apibase.h:2818
#define DiagnosticOutput(formatString,...)
Definition: debugdiagnostics.h:176
void GetSubstances(BaseDocument *const doc, AtomArray *arr, Bool onlySelected)
Defines a reference to an image file to represent a material parameter.
Definition: materialparameter.h:49
Url _absolutePath
Definition: materialparameter.h:56
Definition: materialparameter.h:75
String _assetName
Definition: materialparameter.h:90
Url _absolutePath
Definition: materialparameter.h:82
String _outputChannelName
The name of the substance output according to the GetSubstanceOutput query of the C4D Substance API.
Definition: materialparameter.h:95
Further Reading