Substance Library

Detailed Description

Since
R18
See also
The Substance Overview article.

The Substance library contains everything needed to control the Substance Engine integration in Cinema 4D. Main topics are:

Importing Substance Assets:

Note
There's also the command ID_SUBSTANCE_COMMAND_LOADASSET, which may be shorter, if user interaction is wanted.
void MySubstanceImport()
{
if (doc == nullptr)
return;
// Setup import parameters
Filename fn = "some_path/nice_substance.sbsar";
SUBSTANCE_IMPORT_COPY copyMode = SUBSTANCE_IMPORT_COPY::NO; // do not copy the Substance archive into the project directory and use absolute path to refer to the file
const Bool errPopup = false; // Don't open any error messages
const Bool addUndo = true; // Yes, please add an undo step for the import
const Bool noMaterial = true; // No material will be created on import
BaseList2D* myImportedAsset = nullptr;
// Import
doc->StartUndo(); // DON'T FORGET, mandatory since we chose to add an undo step
result = ImportSubstance(doc, fn, copyMode, errPopup, addUndo, noMaterial, &myImportedAsset);
doc->EndUndo(); // DON'T FORGET, mandatory since we chose to add an undo step
{
// something went wrong, handle error here...
return;
}
// The substance got successfully inserted into the document
// ...
// return;
}
BaseDocument * GetActiveDocument()
Definition: c4d_basedocument.h:498
Definition: c4d_baselist.h:2208
Manages file and path names.
Definition: c4d_file.h:94
PyObject PyObject * result
Definition: abstract.h:43
maxon::Bool Bool
Definition: ge_sys_math.h:55
SUBSTANCE_IMPORT_COPY
Definition: lib_substance.h:280
@ NO
Do not copy file to project directory (absolute file path).
SUBSTANCE_IMPORT_RESULT
Definition: lib_substance.h:266
SUBSTANCE_IMPORT_RESULT ImportSubstance(BaseDocument *const doc, const Filename &fn, SUBSTANCE_IMPORT_COPY &copyFile, Bool errPopup, Bool addUndo, Bool createMaterial, BaseList2D **assetPtr)
const char * doc
Definition: pyerrors.h:226

Auto-creating basic material from a Substance:

void MySubstanceCreateMaterial()
{
if (doc == nullptr)
return;
if (asset == nullptr)
{
// No Substance asset in the scene
return;
}
const Int32 graphIdx = 0; // Use the first graph of the Substance
const SUBSTANCE_MATERIAL_MODE mode = SUBSTANCE_MATERIAL_MODE::METALLIC; // Use PBR metallic/roughness workflow
BaseMaterial* const mat = CreateMaterial(myImportedAsset, graphIdx, mode);
if (mat == nullptr)
{
// Failed to create material
return;
}
doc->InsertMaterial(mat);
}
Definition: c4d_basematerial.h:28
const wchar_t * mode
Definition: fileutils.h:96
maxon::Int32 Int32
Definition: ge_sys_math.h:60
SUBSTANCE_MATERIAL_MODE
Definition: lib_substance.h:252
@ METALLIC
Create metallic material.
BaseMaterial * CreateMaterial(BaseList2D *const asset, Int32 graphIndex, SUBSTANCE_MATERIAL_MODE mode)
BaseList2D * GetFirstSubstance(BaseDocument *const doc)

Iterate over all graphs, inputs and outputs of a Substance:

void MyPrintAllSubstances()
{
if (doc == nullptr)
return;
AutoAlloc<AtomArray> arrSubstances;
if (arrSubstances == nullptr)
return;
const Bool onlySelected = false; // Get all Substances in the document
GetSubstances(doc, arrSubstances, onlySelected);
for (Int32 idxSubstance = 0; idxSubstance < arrSubstances->GetCount(); ++idxSubstance)
{
BaseList2D* const asset = static_cast<BaseList2D*>(arrSubstances->GetIndex(idxSubstance));
if (asset == nullptr)
continue; // This should not happen, but safe is safe
GePrint("Substance: " + asset->GetName();
String graphName = "";
void* lastGraph = nullptr, graph = nullptr;
while (graph = GetSubstanceGraph(asset, lastGraph, graphName))
{
GePrint(" Graph: " + graphName);
UInt32 inputUid;
Int32 inputDescId;
Int32 inputNumElements;
String inputName;
void* lastInput = nullptr, input = nullptr;
GePrint(" Inputs:");
while (input = GetSubstanceInput(asset, graph, lastInput, inputUid, inputDescId, inputNumElements, inputType, inputName))
{
GePrint(" " + inputName + " (" + String::HexToString(inputUid) + ", " + String::IntToString(inputDescId) + ", " + String::IntToString(inputNuMElements) + ", " + String::IntToString((Int32)inputType) + ")");
lastInput = input;
}
UInt32 outputUid;
String outputName;
void* lastOutput = nullptr, output = nullptr;
GePrint(" Outputs:");
while (output = GetSubstanceOutput(asset, graph, lastOutput, outputUid, outputType, outputName, nullptr))
{
GePrint(" " + outputName + " (" + String::HexToString(outputUid) + ", " + String::IntToString((Int32)outputType) + ")");
lastOutput = output;
}
lastGraph = graph;
}
}
}
void GePrint(const maxon::String &str)
Definition: ge_autoptr.h:37
String GetName() const
Definition: c4d_baselist.h:2381
Definition: c4d_string.h:39
static String HexToString(UInt32 v, Bool prefix0x=true)
Definition: c4d_string.h:478
static String IntToString(Int32 v)
Definition: c4d_string.h:495
Py_ssize_t char * output
Definition: unicodeobject.h:985
maxon::UInt32 UInt32
Definition: ge_sys_math.h:61
SUBSTANCE_INPUT_TYPE
Definition: lib_substance.h:292
SUBSTANCE_OUTPUT_TYPE
Definition: lib_substance.h:315
void GetSubstances(BaseDocument *const doc, AtomArray *arr, Bool onlySelected)
void * GetSubstanceInput(BaseList2D *const asset, void *const graph, void *const prevInput, UInt32 &inputUid, Int32 &firstId, Int32 &numElements, SUBSTANCE_INPUT_TYPE &type, String &name)
void * GetSubstanceOutput(BaseList2D *const asset, void *const graph, void *const prevOutput, UInt32 &outputUid, SUBSTANCE_OUTPUT_TYPE &type, String &name, BaseBitmap **bmpPtr)
void * GetSubstanceGraph(BaseList2D *const asset, void *const prevGraph, String &name)

Changing Substance input parameters:

This basically works the same as with every other NodeData based entity in Cinema 4D, via SetParameter().

See also
SUBSTANCE_INPUT_TYPE
Warning
Under no circumstances the BaseContainer of a Substance assets should be accessed directly. The IDs for use with SetParameter() can be obtained via GetSubstanceInput().

Chapter Substance shader and its parameters:

The Substance shader has two parameters, SUBSTANCESHADER_ASSET and SUBSTANCESHADER_CHANNEL.

Groups

 SUBSTANCE_IMPORT_COPY
 
 SUBSTANCE_IMPORT_RESULT
 
 SUBSTANCE_INPUT_TYPE
 
 SUBSTANCE_MATERIAL_MODE
 
 SUBSTANCE_OUTPUT_TYPE
 
 Substance Command IDs
 
 Substance Message IDs
 
 Substance Plugin IDs
 

Classes

struct  SubstanceShdGetBitmap
 

Create

SUBSTANCE_IMPORT_RESULT ImportSubstance (BaseDocument *const doc, const Filename &fn, SUBSTANCE_IMPORT_COPY &copyFile, Bool errPopup, Bool addUndo, Bool createMaterial, BaseList2D **assetPtr)
 
BaseMaterialCreateMaterial (BaseList2D *const asset, Int32 graphIndex, SUBSTANCE_MATERIAL_MODE mode)
 
BaseShaderCreateSubstanceShader (BaseList2D *const asset)
 
Bool AssignChannelToMaterial (BaseList2D *const asset, Material *const c4dMaterial, Int32 channelId, Int32 outputUid, Bool addUndo)
 

Get and Insert

BaseList2DGetFirstSubstance (BaseDocument *const doc)
 
void GetSubstances (BaseDocument *const doc, AtomArray *arr, Bool onlySelected)
 
Bool InsertLastSubstance (BaseDocument *const doc, BaseList2D *asset)
 

Graphs, Inputs, Outputs

void * GetSubstanceGraph (BaseList2D *const asset, void *const prevGraph, String &name)
 
void * GetSubstanceInput (BaseList2D *const asset, void *const graph, void *const prevInput, UInt32 &inputUid, Int32 &firstId, Int32 &numElements, SUBSTANCE_INPUT_TYPE &type, String &name)
 
void * GetSubstanceOutput (BaseList2D *const asset, void *const graph, void *const prevOutput, UInt32 &outputUid, SUBSTANCE_OUTPUT_TYPE &type, String &name, BaseBitmap **bmpPtr)
 

Preferences

SUBSTANCE_MATERIAL_MODE PrefsGetMaterialModeSetting ()
 
Int32 PrefsGetPreviewSetting ()
 

Misc

Bool MaterialUsesSubstance (BaseMaterial *const mat)
 
BaseBitmapGetSubstanceMosaicPreview (BaseList2D *const asset, Int32 w, Int32 h)
 

Private

void UpdateImageInputPaths (BaseList2D *const asset, String &path)
 
void CloneReferencedSubstances (BaseDocument *const doc, BaseShader *const shd, BaseDocument *const ddoc, BaseShader *const dshd)
 
void CloneReferencedSubstancesObject (BaseDocument *const docSrc, BaseObject *const opSrc, BaseDocument *const docDst, BaseObject *const opDst)
 
void InsertSubstancePreviewScene (BaseDocument *const doc, BaseList2D *const asset)
 
const BaseBitmapGetContentBrowserOverlay ()
 

Function Documentation

◆ ImportSubstance()

SUBSTANCE_IMPORT_RESULT ImportSubstance ( BaseDocument *const  doc,
const Filename fn,
SUBSTANCE_IMPORT_COPY copyFile,
Bool  errPopup,
Bool  addUndo,
Bool  createMaterial,
BaseList2D **  assetPtr 
)

Imports a Substance Asset file (.sbsar) into doc.

Since
R18
Parameters
[in]docThe document to import into.
[in]fnThe Substance Asset file.
[in,out]copyFileThe copy file flag: SUBSTANCE_IMPORT_COPY. Determines if Substance Asset files are copied into the project folder (and therefore referenced with relative path).
If set to SUBSTANCE_IMPORT_COPY::ASK, user's choice will be returned.
Note: When set to SUBSTANCE_IMPORT_COPY::ASK, the function obviously has to be called in a context, where user interaction is allowed.
[in]errPopupIf set to true, problems will be communicated to the user with a message requester.
Note: When set to true, the function obviously has to be called in a context, where user interaction is allowed.
[in]addUndoIf set to true, an undo step will be added for the import. Caller has to care for the surrounding BaseDocument::StartUndo() and BaseDocument::EndUndo() calls.
[in]createMaterialSet to true, to have a material created based on the configuration in preferences. Set to false, to suppress any creation of materials.
[in,out]assetPtrA pointer to a Substance asset pointer. If not nullptr, the pointer to the imported Substance Asset will be returned here.
Returns
The result for the import: SUBSTANCE_IMPORT_RESULT

◆ CreateMaterial()

BaseMaterial* CreateMaterial ( BaseList2D *const  asset,
Int32  graphIndex,
SUBSTANCE_MATERIAL_MODE  mode 
)

Creates a Cinema 4D standard material from asset.

Since
R18
Parameters
[in]assetThe Substance asset.
[in]graphIndexThe index of the graph to use (for multi-graph Substances).
[in]modeThe material creation mode: SUBSTANCE_MATERIAL_MODE
Returns
The created material. The caller owns the pointed material.

◆ CreateSubstanceShader()

BaseShader* CreateSubstanceShader ( BaseList2D *const  asset)

Creates a Substance shader linked to asset.

Since
R18
Parameters
[in]assetThe Substance asset (may be nullptr).
Returns
The created Substance shader. The caller owns the pointed shader.

◆ AssignChannelToMaterial()

Bool AssignChannelToMaterial ( BaseList2D *const  asset,
Material *const  c4dMaterial,
Int32  channelId,
Int32  outputUid,
Bool  addUndo 
)

Creates a Substance shader, links it to asset, sets the Substance output to outputUid and assigns the shader to channelId of c4dMaterial.

Since
R18
Parameters
[in]assetThe Substance asset, the pointed Substance asset needs to be part of the document.
[in]c4dMaterialThe Material.
[in]channelIdThe channel ID: CHANNEL
[in]outputUidThe unique ID of the Substance output to use.
[in]addUndoIf set to true, an undo step will be added for the import. Caller has to care for the surrounding BaseDocument::StartUndo() and BaseDocument::EndUndo() calls.
Returns
true if successful, otherwise false.

◆ GetFirstSubstance()

BaseList2D* GetFirstSubstance ( BaseDocument *const  doc)

Retrieves a pointer to the first Substance asset in doc.

Since
R18
Parameters
[in]docThe document.
Returns
The first Substance asset or nullptr, if none exists. Cinema 4D owns the pointed Substance asset.

◆ GetSubstances()

void GetSubstances ( BaseDocument *const  doc,
AtomArray arr,
Bool  onlySelected 
)

Retrieves all (or only selected) substances assets doc.

Since
R18
Parameters
[in]docThe document.
[in]arrThe AtomArray to fill. The caller owns the pointed array.
[in]onlySelectedSet to true to get only selected Substance assets.

◆ InsertLastSubstance()

Bool InsertLastSubstance ( BaseDocument *const  doc,
BaseList2D asset 
)

Inserts asset into doc (as last element).

Since
R18
Parameters
[in]docThe document.
[in]assetThe Substance asset. On success Cinema 4D takes over the ownership of the pointed Substance asset.
Returns
true if success, otherwise false.

◆ GetSubstanceGraph()

void* GetSubstanceGraph ( BaseList2D *const  asset,
void *const  prevGraph,
String name 
)

Retrieves the Substance graph. This function may be used to iterate over the graphs of asset.

Since
R18
Parameters
[in]assetThe Substance asset.
[in]prevGraphPass nullptr to get the first graph, pass a graph pointer to get the following graph.
[out]nameName of the returned graph. Only valid if return value != nullptr.
Returns
A pointer to identify the graph, may not be dereferenced. nullptr if graph is not available. Cinema 4D owns the pointed graph.

◆ GetSubstanceInput()

void* GetSubstanceInput ( BaseList2D *const  asset,
void *const  graph,
void *const  prevInput,
UInt32 inputUid,
Int32 firstId,
Int32 numElements,
SUBSTANCE_INPUT_TYPE type,
String name 
)

Retrieves a Substance input of an asset. This function may be used to iterate over the inputs of a graph of asset.

Since
R18
Parameters
[in]assetThe Substance asset.
[in]graphThe graph.
[in]prevInputPass nullptr to get the first input, pass an input pointer to get the following input.
[out]inputUidThe unique ID of the input. Only valid if return value != nullptr.
[out]firstIdThe ID of the first component of the input parameter in Cinema 4D (see also numElements). This ID can be used to create a DescID for C4DAtom::SetParameter(). Only valid if return value != nullptr.
[out]numElementsThe number of description elements used in Cinema 4D to represent the Substance input parameter. Only valid if return value != nullptr.
[out]typeThe data type of the input: SUBSTANCE_INPUT_TYPE. Only valid if return value != nullptr.
[out]nameName of the returned input. Only valid if return value != nullptr.
Returns
A pointer to identify the input, may not be dereferenced. nullptr if input is not available. Cinema 4D owns the pointed input.

◆ GetSubstanceOutput()

void* GetSubstanceOutput ( BaseList2D *const  asset,
void *const  graph,
void *const  prevOutput,
UInt32 outputUid,
SUBSTANCE_OUTPUT_TYPE type,
String name,
BaseBitmap **  bmpPtr 
)

Retrieves a Substance input of an asset. This function may be used to iterate over the outputs of a graph of asset.

Since
R18
Parameters
[in]assetThe Substance asset.
[in]graphThe graph.
[in]prevOutputPass nullptr to get the first output, pass an output pointer to get the following output.
[out]outputUidThe unique ID of the output. Only valid if return value != nullptr.
[out]typeThe output type ID. Only valid if return value != nullptr.
[out]nameThe name of the returned output. Only valid if return value != nullptr.
[in,out]bmpPtrA pointer to a BaseBitmap pointer. If not nullptr, a pointer to a clone of the output channel bitmap will be returned here. The caller owns the pointed BaseBitmap.. Only valid if return value != nullptr.
Returns
A pointer to identify the output, may not be dereferenced, Cinema 4D owns the pointed output., or nullptr if output is not available

◆ PrefsGetMaterialModeSetting()

SUBSTANCE_MATERIAL_MODE PrefsGetMaterialModeSetting ( )

Convenience function to get the material creation mode set in Substance preferences.

Since
R18
Returns
The material creation mode: SUBSTANCE_MATERIAL_MODE

◆ PrefsGetPreviewSetting()

Int32 PrefsGetPreviewSetting ( )

Convenience function to get the preview mode for Content Browser set in Substance preferences.

Since
R18
Returns
Zero for mosaic preview, otherwise rendered preview scene.

◆ MaterialUsesSubstance()

Bool MaterialUsesSubstance ( BaseMaterial *const  mat)

Checks if mat contains any Substance shaders.

Since
R18
Parameters
[in]matThe material to check for Substance shaders.
Returns
true if the material uses a Substance shader, otherwise false.

◆ GetSubstanceMosaicPreview()

BaseBitmap* GetSubstanceMosaicPreview ( BaseList2D *const  asset,
Int32  w,
Int32  h 
)

Returns an image with previews of the output channels of asset.

Since
R18
Note
While the Substance asset won't have to be re-rendered, this operation still involves downscaling of all Substance outputs.
Parameters
[in]assetThe Substance asset.
[in]wThe width of the preview image.
[in]hThe weight of the preview image.
Returns
A pointer to the resulting bitmap. The caller owns the pointed BaseBitmap.

◆ UpdateImageInputPaths()

void UpdateImageInputPaths ( BaseList2D *const  asset,
String path 
)

Private.

Since
R18

◆ CloneReferencedSubstances()

void CloneReferencedSubstances ( BaseDocument *const  doc,
BaseShader *const  shd,
BaseDocument *const  ddoc,
BaseShader *const  dshd 
)

Private.

Since
R18

◆ CloneReferencedSubstancesObject()

void CloneReferencedSubstancesObject ( BaseDocument *const  docSrc,
BaseObject *const  opSrc,
BaseDocument *const  docDst,
BaseObject *const  opDst 
)

Private.

Since
R18

◆ InsertSubstancePreviewScene()

void InsertSubstancePreviewScene ( BaseDocument *const  doc,
BaseList2D *const  asset 
)

Private.

Since
R18

◆ GetContentBrowserOverlay()

const BaseBitmap* GetContentBrowserOverlay ( )

Returns the Substance logo bitmap. Private.

Since
R19
Returns
The logo bitmap. Cinema 4D owns the pointed BaseBitmap.