About

MultipassBitmap is a subclass of BaseBitmap that provides support for multiple folders and layers. Such a folder or layer is represented as another MultipassBitmap.

Warning
For MAXON API image classes see Images Manual. For MAXON API media input and output see Media Sessions Manual.
// This example creates a new MultipassBitmap with a custom layer.
// The bitmap is saved as a multi layer TIFF file.
const Int32 width = 1920;
const Int32 height = 1080;
const COLORMODE colorMode = COLORMODE::RGBf;
// create MultipassBitmap with the given dimensions and color mode
MultipassBitmap* multipassBitmap = MultipassBitmap::Alloc(width, height, colorMode);
if (multipassBitmap == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// add a new layer
MultipassBitmap* const layer = multipassBitmap->AddLayer(nullptr, colorMode);
if (layer)
{
layer->SetParameter(MPBTYPE::NAME, "Custom Layer");
// fill layer
const Int32 bufferSize = width * 3; // rgb
ifnoerr (PIX_F * lineBuffer = NewMemClear(PIX_F, bufferSize))
{
for (Int32 y = 0; y < height; ++y)
{
const Float32 red = Float32(y) / Float32(height);
Int32 offset = 0;
for (Int32 x = 0; x < width; ++x)
{
const Float32 green = Float32(x) / Float32(width);
// fill line buffer
lineBuffer[offset] = red;
lineBuffer[offset + 1] = green;
lineBuffer[offset + 2] = 0;
offset = offset + 3;
}
// fill line
layer->SetPixelCnt(0, y, width, (UChar*)lineBuffer, COLORBYTES_RGBf, colorMode, PIXELCNT::NONE);
}
DeleteMem(lineBuffer);
}
}
// save to file
Filename imageFileName;
// select a file name
if (imageFileName.FileSelect(FILESELECTTYPE::IMAGES, FILESELECT::SAVE, "Save Image File"_s))
{
imageFileName = GeFilterSetSuffix(imageFileName, FILTER_TIF);
// save as multi layer 32-bit TIF
const IMAGERESULT res = multipassBitmap->Save(imageFileName, FILTER_TIF, nullptr, bits);
if (res != IMAGERESULT::OK)
ApplicationOutput("Error saving image.");
}
// destroy MultipassBitmap
MultipassBitmap::Free(multipassBitmap);

Access

A MultipassBitmap can be cast into a VPBuffer and vice versa in the rendering pipeline. If a given BaseBitmap pointer refers to a MultipassBitmap can be checked with BaseBitmap::IsMultipassBitmap().

Allocation/Deallocation

A MultipassBitmap can be created with the usual tools:

// This example creates a new MultipassBitmap.
const Int32 width = 1920;
const Int32 height = 1080;
const COLORMODE colorMode = COLORMODE::RGB;
// allocate MultipassBitmap with the given settings
MultipassBitmap* multipassBitmap = MultipassBitmap::Alloc(width, height, colorMode);
if (multipassBitmap == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// use MultipassBitmap
// destroy MultipassBitmap
MultipassBitmap::Free(multipassBitmap);

A multi-layer image file can also be loaded into a MultipassBitmap using BaseBitmap::Init():

// This example lets the user select an image file that will be loaded.
// If the loaded image contains layers the layout count is printed.
Filename selectedImageFile;
// select image file
if (!selectedImageFile.FileSelect(FILESELECTTYPE::IMAGES, FILESELECT::LOAD, "Select Image"_s))
return maxon::OK;
// load image file
BaseBitmap* bitmap = nullptr;
const IMAGERESULT result = BaseBitmap::Init(bitmap, selectedImageFile);
// check success
if (result != IMAGERESULT::OK)
return maxon::IoError(MAXON_SOURCE_LOCATION, MaxonConvert(selectedImageFile, MAXONCONVERTMODE::NONE), "Could not load image file."_s);
// check if it is a MultipassBitmap
if (bitmap->IsMultipassBitmap())
{
MultipassBitmap* const multipassBitmap = static_cast<MultipassBitmap*>(bitmap);
// get layer count
const Int32 layerCount = multipassBitmap->GetLayerCount();
ApplicationOutput("Layer Count: " + String::IntToString(layerCount));
}
else
{
// no MultipassBitmap, no layers
ApplicationOutput("No layers");
}

The image data stored in the layers can easily be deleted with:

Properties

Parameters

Multiple parameters can be set to define the behaviour of a given layer:

Note
Since a MultipassBitmap is used within the rendering pipeline some of these parameters are only relevant in that context.

The parameter IDs are:

Some of these parameters can be directly accessed with these convenience functions:

// This example adds and configures a new MultipassBitmap layer.
// add a new layer
MultipassBitmap* const layer = multipassBitmap->AddLayer(nullptr, colorMode);
if (layer)
{
// configure new layer
layer->SetName("New Layer"_s);
layer->SetParameter(MPBTYPE::SHOW, true);
layer->SetParameter(MPBTYPE::SAVE, false);
}
// show bitmap in Picture Viewer
ShowBitmap(multipassBitmap);

Layers

A MultipassBitmap can contain default layers, alpha layers and hidden layers:

These layers are accessed with:

// This example loops through all layers of
// the given MultipassBitmap.
// get layer count
const Int32 layerCount = multipassBitmap->GetLayerCount();
// loop through all layers
for (Int32 layerIndex = 0; layerIndex < layerCount; ++layerIndex)
{
MultipassBitmap* const layer = multipassBitmap->GetLayerNum(layerIndex);
if (layer)
{
// access and print layer name
const String layerName = layer->GetParameter(MPBTYPE::NAME).GetString();
ApplicationOutput("Layer: " + layerName);
}
}

Layers, folders and alpha layers are added with:

Further layer related functions are:

// This example adds a new folder with two layers
// to the given MultipassBitmap.
// add a new folder
MultipassBitmap* const folder = multipassBitmap->AddFolder(nullptr);
if (folder)
{
folder->SetName("Folder"_s);
// add a new layer
MultipassBitmap* const layerA = folder->AddLayer(nullptr, colorMode);
if (layerA)
{
// configure new layer
layerA->SetName("Layer A"_s);
layerA->SetParameter(MPBTYPE::SHOW, true);
layerA->SetParameter(MPBTYPE::SAVE, true);
}
// add a new layer
MultipassBitmap* const layerB = folder->AddLayer(nullptr, colorMode);
if (layerB)
{
// configure new layer
layerB->SetName("Layer B"_s);
layerB->SetParameter(MPBTYPE::SHOW, true);
layerB->SetParameter(MPBTYPE::SAVE, true);
}
}

Convert

The content of a MultipassBitmap can also be represented as a BodyPaint PaintBitmap:

// This example accesses the PaintBitmap representation of the
// given MultipassBitmap. The functions of the PaintBitmap class
// are used to merge the layers into one BaseBitmap.
AutoAlloc<BaseBitmap> mergedBitmap;
if (mergedBitmap == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// get PaintBitmap representation
PaintBitmap* const paintBitmap = multipassBitmap->GetPaintBitmap();
if (paintBitmap == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// use PaintBitmap functionality to merge layers
const Int32 width = multipassBitmap->GetBw();
const Int32 height = multipassBitmap->GetBh();
const Int32 calcFlags = RECALC_NOGRID | RECALC_INITBMP;
// merge layers into one BaseBitmap
if (!paintBitmap->ReCalc(nullptr, 0, 0, width, height, mergedBitmap, calcFlags, 0))
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
ShowBitmap(mergedBitmap);

Further Reading

BaseBitmap::IsMultipassBitmap
Bool IsMultipassBitmap(void) const
COLORMODE::RGB
@ RGB
8-bit RGB channels.
IMAGERESULT::OK
@ OK
Image loaded/created.
FILESELECTTYPE::IMAGES
@ IMAGES
Image files.
MPBTYPE::NAME
@ NAME
String Get/Set. The layer name.
LAYER_ADD
@ LAYER_ADD
Definition: bplayer.h:40
MPBTYPE::BLENDMODE
@ BLENDMODE
Int32 Get/Set. The blend mode (LAYER_NORMAL, LAYER_DISSOLVE etc. from bplayer.h).
FILESELECT::SAVE
@ SAVE
Save dialog.
NewMemClear
#define NewMemClear(T, cnt)
Definition: defaultallocator.h:205
PaintBitmap
The base class of all paint classes. Can be a texture, material, layer or mask.
Definition: c4d_painter.h:398
MultipassBitmap::GetPaintBitmap
PaintBitmap * GetPaintBitmap()
Definition: c4d_basebitmap.h:1127
ifnoerr
#define ifnoerr(...)
The opposite of iferr.
Definition: errorbase.h:385
Float32
maxon::Float32 Float32
Definition: ge_sys_math.h:53
Filename
Manages file and path names.
Definition: c4d_file.h:81
maxon::OK
return OK
Definition: apibase.h:2490
MultipassBitmap::GetLayerNum
MultipassBitmap * GetLayerNum(Int32 num)
Definition: c4d_basebitmap.h:1005
PaintBitmap::ReCalc
Bool ReCalc(BaseThread *thread, Int32 x1, Int32 y1, Int32 x2, Int32 y2, BaseBitmap *bmp, Int32 flags, UInt32 showbit)
Definition: c4d_painter.h:532
MultipassBitmap::AddLayer
MultipassBitmap * AddLayer(MultipassBitmap *insertafter, COLORMODE colormode, Bool hidden=false)
Definition: c4d_basebitmap.h:1028
MAXONCONVERTMODE::NONE
@ NONE
No check if file exists under case-sensitive drives.
MAXON_SOURCE_LOCATION
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:66
BaseBitmap::Free
static void Free(BaseBitmap *&bm)
BaseBitmap::Init
static IMAGERESULT Init(BaseBitmap *&res, const Filename &name, Int32 frame=-1, Bool *ismovie=nullptr, BitmapLoaderPlugin **loaderplugin=nullptr, const maxon::Delegate< void(Float progress)> &progressCallback=nullptr)
COLORBYTES_RGBf
#define COLORBYTES_RGBf
Floating point RGB.
Definition: c4d_basebitmap.h:82
MultipassBitmap::GetLayerCount
Int32 GetLayerCount() const
Definition: c4d_basebitmap.h:980
UChar
maxon::UChar UChar
Definition: ge_sys_math.h:42
MPBTYPE::SHOW
@ SHOW
Bool Get/Set. Determines if the layer will be shown in the external render window....
BaseBitmap::GetBw
Int32 GetBw(void) const
Definition: c4d_basebitmap.h:546
MPBTYPE::SAVE
@ SAVE
Bool Get/Set. Determines if the layer is saved with the image or not if SAVEBIT::USESELECTEDLAYERS is...
MultipassBitmap::SetName
void SetName(const maxon::String &name)
MaxonConvert
maxon::Url MaxonConvert(const Filename &fn, MAXONCONVERTMODE convertMode)
FILTER_TIF
#define FILTER_TIF
TIFF.
Definition: ge_prepass.h:174
SAVEBIT::MULTILAYER
@ MULTILAYER
Save multiple layers.
String
Definition: c4d_string.h:35
String::IntToString
static String IntToString(Int32 v)
Definition: c4d_string.h:492
SAVEBIT::USE32BITCHANNELS
@ USE32BITCHANNELS
Use 32-bit channels.
MultipassBitmap
Definition: c4d_basebitmap.h:935
MultipassBitmap::GetParameter
GeData GetParameter(MPBTYPE id) const
Definition: c4d_basebitmap.h:1095
COLORMODE
COLORMODE
Definition: ge_prepass.h:436
maxon::DeleteMem
void DeleteMem(T *&p)
Definition: defaultallocator.h:258
BaseBitmap::GetBh
Int32 GetBh(void) const
Definition: c4d_basebitmap.h:552
RECALC_INITBMP
#define RECALC_INITBMP
Initialize the BaseBitmap of the bmp parameter.
Definition: c4d_painter.h:537
MultipassBitmap::SetParameter
Bool SetParameter(MPBTYPE id, const GeData &par)
Definition: c4d_basebitmap.h:1103
PIXELCNT::NONE
@ NONE
None.
Int32
maxon::Int32 Int32
Definition: ge_sys_math.h:45
ApplicationOutput
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:209
ShowBitmap
Bool ShowBitmap(const Filename &fn)
MultipassBitmap::AddFolder
MultipassBitmap * AddFolder(MultipassBitmap *insertafter, Bool hidden=false)
Definition: c4d_basebitmap.h:1036
GeData::GetString
const String & GetString(void) const
Definition: c4d_gedata.h:447
FILESELECT::LOAD
@ LOAD
Load dialog.
COLORMODE::RGBf
@ RGBf
32-bit floating point RGB channels.
RECALC_NOGRID
#define RECALC_NOGRID
If set the checkered background grid will not be evaluated.
Definition: c4d_painter.h:536
BaseBitmap
Definition: c4d_basebitmap.h:406
AutoAlloc
Definition: ge_autoptr.h:32
PIX_F
Float32 PIX_F
32-bit float pixel type.
Definition: ge_math.h:19
BaseBitmap::SetPixelCnt
Bool SetPixelCnt(Int32 x, Int32 y, Int32 cnt, UChar *buffer, Int32 inc, COLORMODE srcmode, PIXELCNT flags)
Definition: c4d_basebitmap.h:746
GeFilterSetSuffix
Filename GeFilterSetSuffix(const Filename &name, Int32 id)
IMAGERESULT
IMAGERESULT
Definition: ge_prepass.h:3618
BaseBitmap::Save
IMAGERESULT Save(const Filename &name, Int32 format, BaseContainer *data, SAVEBIT savebits) const
BaseBitmap::Alloc
static BaseBitmap * Alloc(void)
SAVEBIT
SAVEBIT
Definition: ge_prepass.h:260
MultipassBitmap::Free
static void Free(MultipassBitmap *&bm)
Filename::FileSelect
Bool FileSelect(FILESELECTTYPE type, FILESELECT flags, const maxon::String &title, const maxon::String &force_suffix=maxon::String())