Hey, good news, this is fixed in the upcoming hotfix (2026.3.2).
administrators
Posts
-
RE: TimeLine DopeSheet not update
-
RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable
Hey @ThomasB,
so, I had a look and figured it out. When you diff the two objects from my file, there are quite few differences (as I was not 100% faithful in copying all values), but the culprit is this:

The RS Light uses a standard light to accomplish its VP representation. When you disable the 'Illumination' checkmark, the RS Light
GetVirtualObjectswill simply return a null object, i.e., the behavior you experienced. I filed a ticket for this (ITEM#651586 Inconsistent Redshift Light 'Make Editable' behavior), as I would consider this so unintuitive that it borders on a bug. But this is outside of the SDK/Cinema 4D domain, so I cannot just fix it myself.In Python, there is currently no way to fix this on your side. The message
MSG_CURRENTSTATE_ENDis not wrapped for Python (with it you can manipulate the output of a "Make Editable" action before it is inserted). The other route, the build flags on HierarchyHelp are also not possible in Python either, becauseHierarchyHelpis also not wrapped for Python.But I just changed the latter route, and in the next major update you will be able to react to build flags. There will also be a new code example named
py-objectdata_buildflags_2027which showcases this feature. You can then react to your object being made editable, built for rendering, built for export, etc. and react by changing its output.In your case you would then probably not disable the illumination when your object is being made editable. So, for now, you either have to live with the behavior, or turn on "preview > illumination".
Cheers,
FerdinandResult
The output, i.e., diff, with the offending line highlighted.

Code
This assumes my scene from above with everything deleted but the two objects.
import c4d import mxutils import difflib doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. def main() -> None: """Called by Cinema 4D when the script is being executed. """ data: list[str] = [ mxutils.GetParameterTreeString(node) for node in mxutils.IterateTree(doc.GetFirstObject(), True) ] # Diff the first two strings in the list and print the result to the console. if len(data) < 2: return c4d.gui.MessageDialog("Not enough data to perform diff.") a: str = data[0] b: str = data[1] diff: list[str] = list(difflib.unified_diff(a.splitlines(), b.splitlines(), lineterm='')) if not diff: print("No differences found.") print("\n".join(diff)) print("\n\n" + "=" * 80 + "\n\n") print(a) print("\n" + "-" * 80 + "\n") print(b) c4d.EventAdd() if __name__ == '__main__': main() -
RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable
Thanks, I will have a look. This all is starting to make sense now. We rewrote the RS Light and Camera objects a while ago. And at least the RS Camera object is not absolutely non-trivial to operate. This either sounds like that you have to jump through specific hoops or there is a bug in the importer code, that transforms pre 2024 Light and Camera objects (I think this was when we revamped them).
It might take me a week or so to figure this out. When this is very urgent for you, I would recommend fixing the scene(s) by manually recreating the lights. You could probably also automate this by just selectively copying data (which is likely going to be the solution I am going to provide, unless I come to the conclusion that this must be fixed on our side, as for example the importer being faulty).
Cheers,
Ferdinand -
RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable
Hey @ThomasB,
I do not think that this is an API issue. I do not meant with that that I will not help you, as this still happens in the context of a plugin, I say this simply to classify the issue.
When I try to manually open your
build_1.c4dfile, it loads in 2026.2.0 but when I then press C on that light in question, I get exactly the output you report. And I cannot really explain why as this is just a normal rectangle shape area light (well, I sort of can, see below
).
The plot however thickens when I try to open the file with 2026.3.1:

This file seems to be somehow corrupted. After some poking around I manged to create this build_2.c4d which loads in 2026.3. But the light still did not work correctly. I then created a new RS light instance and copied over the whole data container via
Get/SetData, which again resulted in a broken light. Only when I manually recreated the light by manually copying values, I ended up with a valid light. Which then also revealed that this light should have a much different light representation in the VP.Your light:

The manual copy:

I.e., you seem to have there a fundamentally corrupted scene and especially light objects. The fact that I could reproduce this with a fresh light instance and a
Get/SetDatacopy indicates this the data container of the light is corrupted. We could now start comparing the data containers of your light and the manually created one, to dive deeper, but I think I stop here for now. Did you programmatically modify this scene? Because your plugin only seems to load it. The question is now if you have more scenes like this. Otherwise I would just use my fixed scene (which also contains the fixed light) and move one.Cheers,
FerdinandPS: Okay, now I see it, the actual scene in much more complex.
When you want to dig deeper yourself, a great tool to debug this would be mxutils.GetContainerTreeString. You can just dump both containers and then either visually compare them or use a diff tool. Or you use mxutils.GetParameterTreeString directly on the light objects.
-
RE: Sub materials links and undo
Yeah, I got the general direction, that you are probably implementing a material mixer type of material/shader. When you implement a full render engine binding, you should go the event notification route, as I am sure you can then easily handle the (slight) complexity that comes with them.
Regarding the architecture, in principle you can do with whatever you want. As Maxon employee I would of course recommend to use our Nodes API (what you call 'native'). The SDK contains both code examples and documentation about this. But this biggest flaw of the Nodes API is probably that it is not entirely non-trivial. But implementing a full node editor also requires a relatively high level of expertise about our APIs, although in different areas.
Currently Redshift, Vray, Arnold, and CentiLeo use the Nodes API and all other render engines (Corona, Octane, Cycles, etc.) use either a completely custom system or the old Xpresso Nodes API.
Cheers,
FerdinandPS: When you are developing a render engine binding, you might want to consider our Maxon Registered Developer Program.
-
RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable
Hello @ThomasB,
I am sorry that you had a bad experience in the RS forum. Can you show me the actual code where you add the RS light object in code? Because I see no
Orslightin your snippet? Or when you load an asset, share that asset? When I do a quick test with a Python generator object, this works fine for me.Cheers,
FerdinandPS: The plugin link you shared only contains an encrypted plugin (
pypv) which not only makes it harder for me to get to the source code, I also cannot run such plugin on company hardware before I cracked it and can reasonably say that it does not contain dangerous code. Could you please share an unencrypted version? -
RE: Sub materials links and undo
Hello @DronKozy,
Welcome to the Maxon developers forum and its community, it is great to have you with us!
Getting Started
Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.
- Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
- Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
- Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.
It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: How to Ask Questions.
About your First Question
I am afraid there is no really good way to do what you want to do. Without example code, I also have to somewhat guess what is going on. As lined out in our support procedures, we recommend to always accompany questions with compileable code.
I it is a bit fuzzy to me what you are doing, please tell me when I got it wrong. You have a
BaseMaterialimplementation which itself hasLINKparameters which link to other materials. You now want to updateMATPREVIEWparameter manually when your dependencies update.Tracking Changes
Cinema generally follows an opt-out and not an opt-in update/message model. E.g., all objects get their
GetVirtualObjectsmethod called on each scene update, and it is then up to the object to decide if they actually want to update or just keep using their existing cache.The evaluation of materials happens at render time, so there is no direct function which is called or message which is sent to your plugin when something in the scene is being updated. The messages you are using somewhat go into that direction, but you misunderstood a bit their purpose.
MSG_UPDATEis sent when an external entity wants to inform a node that it modified dependent data and that the node should update its internal data (outside of the general scene state rebuild). It is not a message that is being sent each time the node has been updated. I could for example get a point object, modify its points, and then not send that message and that would be totally valid code. The object would only update once Cinema 4D reevaluates the object on its own, but sometimes this is desirable. For user interactions, Cinema 4D will usually send this message, but its purpose is still a bit different from what you think it is. The same goes forMSG_CHANGE.The way to track changes in Cinema 4D, is the dirty system found on C4Datom. Cinema will usually automatically entail updates when the dirtiness of something changed, e.g., when a user changed the parameters of a node. The problem is that for
LINKparameters (and also shader links), changes to the linked node do not count towards the data dirtiness of the node. Or in other words, Cinema does not consider a node A to be changed when the node B changed to which A links. For something like objects this is not really a problem due to the out-out update model, for material previews this means you can get event starved. The video below demonstrates the effect. -
RE: GetWorkplaneMatrix is broken in Cinema 4D 2026.3
This will be fixed in the next upcoming hotfix.