C4D Programming

Developing plugins and scripts for CINEMA 4D

Advance to St-Charles Place, if you pass go collect 200$

by jfyelle

We’ve incorporated this web site’s content to our brand new and generally awesome MAXON’s development support portal.  Please update your bookmark and come with us on our new developers.maxon.net spot.

Thanks – This is our last post on this site.

Cinema 4D R16 Reflectance channel’s API

by jfyelle

In Cinema 4D R16, We replaced specular and reflection by a new channel called reflectance. This channel allows layered materials which can be used to do more realistic materials such as car paints, human skin, etc. In this post, you’ll find how to make the best out of the new feature.

@Can Amerak

@Can Amerak

A layered material is different from the old specular and reflection channels in one important way. It is now possible to do specular AND reflection on the same layer. This means it is may not be possible to find out the specular or the reflection layers in the material. In consequence, we cannot give a specific layer index where specular or reflection may be found.

This paradigm change means exporting consistent looking materials via your favorite interop format will only work if a material has one layer for specular and one layer for reflection.

Who is concerned

R15 .C4D files coming to R16 have their specular and reflection automatically converted to the new reflectance layer. Any plugin dealing with the specular / reflection channels such as material plugins or interop filters need to properly support the new feature.

Header file

The reflectance API is located in header file c4d_reflection.h
#include “c4d_reflection.h”

Accessing the Specular, reflection channels

Because the accesses were remapped, accessing the specular or reflection channels the old way will work for extracting or modifying the information


if (c4d_material->GetChannelState(channelId))
	BaseChannel* channel;
	BaseContainer channel_data;

	Float spec_width, spec_height;
	channel = c4d_material->GetChannel(channelId);
	if (channel)
		channel_data = c4d_material->GetData();

		Float spec_width = channel_data.GetFloat(MATERIAL_SPECULAR_WIDTH);
		Float spec_height = channel_data.GetFloat(MATERIAL_SPECULAR_HEIGHT);

Creating a reflectance channel or layers

Creating specular and reflection won’t work alas. For this, you will need to get your hands dirty and create a reflectance channel using the new API.
We gain access to the reflectance channel through the material data.

//Given a Material* c4d_material
BaseContainer* materialData = c4d_material->GetDataInstance();

As the reflection channel come initialised with one basic specular layer. If you want to control exactly what you are doing, you may want to delete all layers and start fresh.


Adding a layer is simple. You would add a layer for specular (comprising specular and specular color) and another layer for reflection. Setting the data in the layer is pretty straight forward except for a couple details. See below.

ReflectionLayer* layer = c4d_material->AddReflectionLayer();

if (reflLayer != nullptr)
	lLayer->name = “Foobar”;

	Int32 refDataID = lLayer->GetDataID();

	materialData->SetVector(specDataID + REFLECTION_LAYER_COLOR_COLOR, specular_color);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_COLOR_BRIGHTNESS, specular_factor);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_MAIN_VALUE_REFLECTION, 0.0);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_MAIN_VALUE_ROUGHNESS, somevalue);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_MAIN_VALUE_SPECULAR, somevalue);
	materialData->SetFloat(specDataID + REFLECTION_LAYER_MAIN_VALUE_BUMP, 1.0);

Notice how we use the specDataID layer offset to assign the various layer parameters. The ID to access the default specular channel is 0x04. We do not know for sure if a specific layer is the main reflection or specular layer. This knowledge is lost with the possibilities opened by this layer system. The parameter names should be very close to what you see in the user interface. As the vocabulary varies across 3D products and feature, I believe playing with the parameters will help you figure out the fastest what you actually control in the material.

Don’t forget to kick the can when you are done

If you re-initialized the reflectance, you will need one extra step. Once done setting the reflection layer, notify the reflectance system you imported data in or your work will be remapped automatically.

reflectanceData->SetBool(REFLECTION_LAYER_IMPORTED, true);

Hoping this helps. Let me know of any question or details, as we are working the reflectance documentation in.

All the fun you can have with NGons

by jfyelle

Hello everyone,

I’m joining this blog and as a first topic, will be talking about my friend, the Ngon.

As you may know, a PolygonObject is composed of CPolygons which are 4 sided polygons.  The triangle case is supported by using the same vector ID for the c and d members.  There is an abstraction called a NGon that represents 5+ sided polygons.  So, while I was fiddling with them for my own interop related work, I figured I could share a few tips about them and throw a couple freebies in while at it.
Read the rest of this entry »

LONG CYCLEs with icons and separator

by .

You want to display icons in a LONG CYCLE? Easy as pie, this article will show you how it works!
Read the rest of this entry »


by .

Have you ever wondered how to create and use those pretty Description elements that are a combination of a LONG cycle and a command button?

The Character object offers them for component selection. They let you choose an option from a list, perform an action by clicking on it, and they can display icons and look cool. The SDK documentation does not really say anything about that element, but this article will show you how to make use of it.
Read the rest of this entry »

Compiling 64 Bit plugins in Visual C++ Express

by .

Many people, especially developers who write free plugins, or hobbyists, use only the free Visual C++ 2010 Express for their Windows builds. However, that version of C++ does not support 64 Bit builds.

There is an easy solution for this, and many people already know it. But since the questions comes up from time to time, here is how to get Visual C++ 2010 Express to build for 64 Bit, too.
Read the rest of this entry »

Why use Get/SetParameter and Get/SetDParameter

by franz3d78

Usually Cinema4D store settings for nodes and tools in a BaseContainer.
BaseContainer is very useful class that allow you to store different data type in easy way.
But you will notice there are some cases where Cinema don’t store parameter in BaseContainer, for example some of light and camera parameters are not reachable by Get/Set BaseContainer Methods.
Read the rest of this entry »

MAXON Developer Kitchen 2013

by .

On Thursday, June 13th 2013, MAXON is hosting the Developer Kitchen. It will take place in the context of the MAXON User Meeting in Cologne, Germany.

Commercial 3rd party plugin developers are invited to participate, to meet and discuss with MAXON developers, hear interesting presentations about plugin development, and find out more!

The participation is free of charge. To get more information and to apply, please contact MAXON Product Manager Bernd Lutz (b_lutz[at]maxon[dot]net).

Automatically add tags at last position on creation

by .

Usually, when the user attaches a new tag to an object using the “Tags” menu in the Object Manager, the new tag is always added as first element to the object’s tag list.

For some tags, however, it would make sense to rather add them to the end of the object’s tag list. Especially if those tags should ‘layer’ their effects on top of each other (e.g. like multiple texture tags).

If you want your tag to be added to the end of the tag list automatically when it is being created, this article will tell you how.
Read the rest of this entry »

NodeData – what is it good for?

by .

If you’re new to programming for CINEMA 4D, you might have wondered what’s the deal with NodeData and its derivatives (e.g. ObjectData, TagData, ShaderData, et cetera).
When you are writing a plugin object, which is a BaseObject, why do you have to derive your plugin class from ObjectData instead of BaseObject? What is the connection between NodeData and the GeListNode derivatives (BaseObject, BaseTag, BaseShader, et cetera)?
In this article, you’re going to find out.
Read the rest of this entry »

Visual Studio Plugin: Favourite Documents

by .

If you work on bigger projects with a large amount of source files, you might want to be able to store files as a group of favourites and to re-open them all at once later?
The free plugin Favourite Documents makes it possible!
Read the rest of this entry »

Licensing Plugins – Part V – Possible extensions

by .

Writing a plugin that extends the functionality of CINEMA 4D is often only the first step towards a finished product. At one point or another during the work on your plugin you will have to spend some thought a proper license system.

This fifth article shows some possible extensions we can make to the license system to make it more flexible and more comfortable to use.
Read the rest of this entry »

Licensing Plugins – Part IV – The license generator

by .

Writing a plugin that extends the functionality of CINEMA 4D is often only the first step towards a finished product. At one point or another during the work on your plugin you will have to spend some thought a proper license system.

This fourth article shows how to write a license generator, that will create keys we can use to unlock the plugin.
Read the rest of this entry »

Licensing Plugins – Part III – License integration

by .

Writing a plugin that extends the functionality of CINEMA 4D is often only the first step towards a finished product. At one point or another during the work on your plugin you will have to spend some thought a proper license system.

This third article shows how to integrate a license check in your plugin, using the license class that we created in part II.
Read the rest of this entry »

Licensing Plugins – Part II – License implementation

by .

Writing a plugin that extends the functionality of CINEMA 4D is often only the first step towards a finished product. At one point or another during the work on your plugin you will have to spend some thought a proper license system.

This second article shows the implementation of a custom license class that can be used to validate a given license key against the customer’s information.
Read the rest of this entry »