• Sub materials links and undo

    Cinema 4D SDK c++ windows s26
    5
    0 Votes
    5 Posts
    359 Views
    ferdinandF
    @DronKozy 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, Ferdinand PS: When you are developing a render engine binding, you might want to consider our Maxon Registered Developer Program.
  • GetWorkplaneMatrix is broken in Cinema 4D 2026.3

    Moved Bugs c++ 2026
    5
    0 Votes
    5 Posts
    465 Views
    ferdinandF
    This will be fixed in the next upcoming hotfix.
  • 0 Votes
    2 Posts
    385 Views
    ferdinandF
    Hey @ECHekman, well, when a node displays an embedded description (what you exemplify at the case of a BaseLink), it uses a DescriptionCustomGui too. Other parameter types aside from a BaseLink which can do this are for example field lists. I am quite frankly a bit surprised that this even bubbles up in the form you report it, that you get a DescID which is selected inside a DescriptionCustomGui that is shown by the node in the DescriptionCustomGui you opened yourself. Attribute Manger selection states (and by extension DescriptionCustomGui) are not a public API feature, as we usually keep our GUIs sealed, i.e., inaccessible to third parties. DescriptionCustomGui is here a bit in a grey area, but I am afraid there is no way to do what you want to do. To do what you want to do, you would need access to internal systems. And other than in some other cases, where we do not always had the time to expose something (and are open to the idea of changing something), this is for GUIs not the case; they are intentionally sealed as we do not want third parties to change basic UX concepts. My general advice would also be to not to try to overcome this boundary (that a plugin reacts to which parameter in a node is being highlighted by the user), as you break UX conventions of Cinema 4D with that. Cheers, Ferdinand You can do this, but it is very hacky: Get the description of the node(s) you are currently displaying in the your DescriptionCustomGui. Check if desc is a member via CheckDescID (I think GetParameter would also work and return an empty container when the ID does not exist). When the ID does not exist, start browsing the container for parameters that are of a DTYPE that implies an underlying node, such as DTYPE_BASELINK. When you find such parameter, get the node node, and check there. Rinse and repeat recursively. Issues: You cannot distinguish the case where an object A has two BaseLink parameters which both hold an object of type T, but not the same instances. You will run into issues with DescID translations which some nodes might do. This is a really big point, which is probably already overlooked in your current code. Nested node relations can get REALLY complicated. BaseLink is trivial, but stuff like field lists, volume lists, or some special shader stuff can get really complicated. You would probably only have to worry about base links and field lists in your case, as other renderers are irrelevant for you, but field list alone are already complex enough that I would strongly advise against 'just implementing it'.
  • 0 Votes
    1 Posts
    6k Views
    No one has replied
  • Copy res folder without shortcut

    Cinema 4D SDK c++ windows
    4
    0 Votes
    4 Posts
    504 Views
    ferdinandF
    That is of course also a valid option, just pick the scripting language you are most comfortable with.
  • Shader bitmap rendering with MemoryFileStruct

    Cinema 4D SDK c++
    4
    0 Votes
    4 Posts
    586 Views
    ferdinandF
    Hey, there is no shame in using the 'old' stuff since it is part of our API (and it will stay like that). I just point it out whenever a user is dealing with one of the hollowed out types. My guess would be that there is a threading issue or threading safety mechanism in the way. I think the memory struct stuff is internally using locks to avoid race conditions/corrupted data. When the renderer backend is doing its threading thing, this could cause issues. But ramdisk should work because our assets use the concept heavily (most assets are only a 'promise' which will only be truly created once accessed). You would even profit from the ramdisk caching in the temp folder of Cinema 4D. So, in its simplest form, this should just look like this: void RenderMyDoc(...) { // --- Error Handling and Resource Management ---------------------------------------------------- // Declare heap allocated resources that must be freed once the function exists either normally or // through an error. HeapRescource * myResource = nullptr; BaseBitmap * bmp = nullptr; // Catch any Maxon API error and turn them into the return type of this function and do optional // logging. We could also free resources here, but then we would have to do it twice, once for // normal exit and once for error exit. iferr_scope_handler { // DiagnosticOutput("Error during RenderMyDoc: @", err); return; }; // finally is Maxon API syntax to execute code once a scope (not necessarily a function) is left, // no matter if it is left through normal execution or through an error. This way we can ensure // that resources are freed. finally { if (myResource) HeapResource::Free(myResource); if (bmp) BaseBitmap::Free(bmp); }; // Allocate all the resources we need. When we use AutoAlloc<T>, we would not need the finally block // above, but not all types have an AutoAlloc allocator. myResource = HeapResource::Alloc(); if (!myResource) return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION, "Failed to allocate heap resource."); bmp = ... // --- Main Logic -------------------------------------------------------------------------------- // Create our ramdisk mounting point and an URL within it. In practice, we probably would want this // ramdisk mounting point to be a class member or even a global singleton. RamDiskRef mountingPoint = RamDiskInterface::Create("net.mycompany.ramdisk.foo"_s) iferr_return; const Url ramdiskUrl = (mountingPoint.GetRoot() + "my_virtual.psd"_s) iferr_return; // Call BaseBitmap::Save with the ramdisk URL converted to a Filename. bmp->Save(cinema::MaxonConvert(ramdiskUrl), ...); // ... } Cheers, Ferdinand
  • 2 Votes
    1 Posts
    13k Views
    No one has replied
  • NETWORK_CONNECTTIMEOUT with SSL

    Cinema 4D SDK 2024 c++ 2025 2026
    5
    0 Votes
    5 Posts
    631 Views
    R
    For now I am good. If I need further help, I will send the endpoint and function by email.
  • Batching Slider messages

    Cinema 4D SDK c++ 2026
    5
    0 Votes
    5 Posts
    635 Views
    SteveHill3DS
    Thank you. MSG_DESCRIPTION_USERINTERACTION_END is just what was needed.
  • 2025 SDKs missing files

    Cinema 4D SDK 2025 c++ windows
    2
    0 Votes
    2 Posts
    494 Views
    ferdinandF
    Hello @atg, 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 can see why would think that, but you mixed things there a bit up. The CMake SDK build system was introduced with 2025.2.0 and became the standard with 2026.0.0. Between 2025.2 and 2025.3 we supported both build systems as a grace period for developers to get accustomed. Chances are very good, that you can just copy the CMake setup, i.e., the cmake folder and files such as CMakeLists.txt, CMakePresets.json, and sdk_modules.txt to a 2025.0 folder and it will generate a correct build system for you. But the supported range is only 2025.2+. For older projects you would have to use the old project tool based build system. Since I know what you are trying to do, I would recommend trying copying before you get into the old build system of ours. 2025.2 Release Notes 2025.2 Build System Docs (which covered both the old Project Tool and CMake) Cheers, Ferdinand edit: You will only find the old project tool tooling in old extended SDKs which supported it, such as 2025.2 or 2025.0.1
  • Advice on implementing undo/redo in a Tool

    Cinema 4D SDK c++ 2026
    5
    0 Votes
    5 Posts
    574 Views
    ferdinandF
    Hey @SteveHill3D, Storing a tool state in a tag is possible, but a bit unusual. But generally you are on the right track. Tags are also internally often used as hidden data containers. When you write a modelling tool, you probably already found out that points and polygons are are actually stored in hidden tags on objects. I am not sure though if using tags in tools is a good advice, as injecting all that data all the time into the scene graph is probably not the fastest. It depends a bit on what you are doing, but in general the solution is a bit unusual. Cheers, Ferdinand
  • Xref Material reference

    Moved General Talk windows 2026 2025 c++
    2
    0 Votes
    2 Posts
    639 Views
    ferdinandF
    Hello @Jespersather, thank you for reaching out to us. This is a developer forum, not an end user support forum. We cannot help you here with your end user issues. Please use our Support Center to get end user support for Cinema 4D. I have moved your topic into General Talk. Cheers, Ferdinand
  • C++ SDK Matrix object style distribution

    Cinema 4D SDK 2026 c++
    3
    0 Votes
    3 Posts
    561 Views
    dexD
    Thank you so much Ferdinand! I have a way forward now for my plugin using the EffectorData ModifyPoints() method. Kind regards Fredrik
  • Set View Transform in Picture Viewer

    Cinema 4D SDK c++ 2026
    2
    0 Votes
    2 Posts
    537 Views
    ferdinandF
    Hey @ECHekman, Thank you for reaching out to us. The answer to your question is sort of yesn't. You can set the embedded view transform of a bitmap, which by default will be used by the Picture Viewer. The Picture Viewer like most managers in Cinema 4D is sealed, and we do not want to change that. So, you cannot change what view transform override is used by the Picture Viewer (when the user chooses to ignore the view transform embedded into an image). See Manage Bitmap OCIO Color Profiles for details. Cheers, Ferdinand
  • Import multiple Takes

    Cineware SDK c++
    6
    0 Votes
    6 Posts
    1k Views
    ferdinandF
    Hey @yannickkohn, Thank you for the source code, but pseudo code is often problematic, especially when it contains so many undefined functions. I cannot say much about any bugs, as your code is so 'pseudo' and you do not show the really deep down work (reading curves and keys here). What also is a bit weird is that you use FindOverride. That function is private for a reason. You should set the active take and then just evaluate the scene data or the tracks of scene data when you are interested in animations only. https://studio. Cheers, Ferdinand
  • 0 Votes
    1 Posts
    38k Views
    No one has replied
  • Dynamically Add Massign to Material in Material Editor

    Cinema 4D SDK c++
    2
    0 Votes
    2 Posts
    498 Views
    ferdinandF
    Hey @ECHekman, I currently use INCLUDE Massign in my .res file. However i would like to do this dynamically so that I can change the order at which it is placed in the Material Editor and Attribute Editor. Is there a way to do this? There is no INCLUDE which you could call programmatically in GetDDescription, but there is Description::LoadDescription. When Cinema 4D is asking you to update a certain part of your description, you could try to call it on your description instance but not with its id, but Massign. This is however very likely to fail or cause crashes, because your description is already being processed, I never tried this myself though. Another approach could be to allocate a dummy description, then load your resource (e.g., Massign) into that dummy description, to then copy parameters bit by bit into your active/actual description passed into GetDDescription. But the whole approach of a 'dynamic include' is a bit backwards without context why it has to be this way. Because when you dynamically include something, this also means you have to remove existing data where it shall not be included anymore. Which is possible but unnecessary extra work. Also copying a whole partial description is not a great idea performance wise, GetDDescription is being called a lot. The better approach would be to just include your partial description in your res file in the a place where it might appear and then dynamically change the parent of that container. As this workflow would be the common dynamic description workflow. Additionally Also is there a way to hide settings from the Obaselist group or hide settings in the Material Editor but keep them in the Attribute editor? No, both managers are more or less just a DescriptionCustomGui, they will always show the same data, unless you have access to the implementation (which you do not). When you would implement your own material dialog, with your own DescriptionCustomGui in it, you could mangle what is shown in this particular description view to your liking, there are multiple methods to highlight, filter, and modify a description on that class. To operate this dialog you would then set this description GUI to the material, shader or whatever BaseList2D you want to display, and then either filter or outright modify the description which is being displayed. Cheers, Ferdinand
  • BaseLink across documents

    Cinema 4D SDK c++
    4
    0 Votes
    4 Posts
    702 Views
    ferdinandF
    Hey @WickedP, As I hinted at above, markers are eternally persistent. I.e., you can unload, load, and modify a scene S or the non-cache* node N in it, the node N will always have the same marker. The flag you found has a very special purpose and also very misleading documentation (I just fixed that). Each node in a scene must have a unique marker, as otherwise not only BaseLink but also things like undo and more won't work properly when not each node has exactly one marker and each marker exactly one node (i.e., a bijective or 'one-to-one' relation). But there can be bad actors such as bugs in our codebase or third party plugins which violate that rule. To combat that, Cinema 4D checks the uniqueness of markers of nodes when a scene is being loaded. When it finds duplicate markers, it will open a question dialog, asking the user if he/she wants to repair that scene. When the user says 'yes', only the nodes which had duplicate markers will get a new marker each (so that they are in a bijective marker relation again). This flag you found will suppress this whole behavior, i.e., it will let you load corrupted scenes as is. I would not recommend using it. I am currently not 100% sure what happens when your LoadDocument call is not DIALOGSALLOWED, it looks a bit like that this check then always never runs (which sounds a bit dangerous). Cheers, Ferdinand edit: okay now I see it, the question dialog part has been commented out, so this runs always without asking the user (and with that also without DIALOGSALLOWED), unless you pass the flag NONEWMARKERS. [*] Object and other nodes in caches, i.e., the partial scene graph returned by BaseObject::GetCache and generated by ObjectData::GetVirtualObjects, are allocated each time the cache is being built and therefore also have a new marker each time. But you cannot (or better should not) try to build base links, undos, xrefs, etc. for object and other nodes in caches. TLDR: Markers do not work for caches.
  • 0 Votes
    2 Posts
    472 Views
    ferdinandF
    Hey @ECHekman, Thank you for your question. This is a tricky one. When NodeData::Read is emitted, Cinema 4D is currently reading a file and in the process of deserializing your node; so it indeed is not yet 'fully instantiated', as that is the whole point of the method. You are here not meant to manipulate the scene graph (the node is not yet attached), but read and store data on your plugin hook. I.e., you are supposed to do something with your MyMaterialData and not the GeListNode/BaseMaterial which is being passed in as the first argument of Read. The common workflow is to read data from the HyperFile which is passed in and store it on your NodeData instance. Passed in is also the important version number (which is called for some odd reason disklevel) of your HyperFile container. As always, you are bound to the main thread for scene graph manipulations. So, NodeData::Init is not a good candidate when wanting to poke around in the scene graph, as it can be called off main thread and on dettached dummy nodes. A good approach is to hook into NodeData::Message and listen for MSG_DOCUMENTINFO to catch a document just having been loaded. This is for your specific case of wanting to manipulate nodes which have been deserialized. If you want to manipulate node instantiation, MSG_MENUPREPARE is a god choice. But it is only called for nodes which have been instantiated from direct user interactions such as a menu click. So, MSG_MENUPREPARE is not being emitted for nodes loaded from a file. The drill to do what you want to do would be: [optional] Overwrite NodeData::Read/Write/CopyTo to read, write, and copy custom data, and possibly use/detect different disk levels to catch different versions of a node type being loaded. You would have to match this with incrementing the disk level in your RegisterMaterialPlugin call, so that there are old and new versions of your material type out there. Hook into the document being loaded, check the scene state, and possible data left behind for you by NodeData::Read and ::Init. Manipulate the scene graph to your liking. Cheers, Ferdinand
  • 0 Votes
    3 Posts
    711 Views
    CJtheTigerC
    Hi @ECHekman, Please also think about UX when deciding something like this. Your everyday C4D user expects just about any object to be customizable in this regard, even if they mostly don't use it. And while I think that objects like fields or deformers don't need things like X-Ray or the visibility flags and I think that it would be better to hide those for objects that don't use them, it's still established and expected as a common base. Unless this is something that's adjusted in all of base C4D I don't think it's a good idea to break this sort of user experience for your own plugins. Coherence is a big thing in UX if you want to make your plugin feel like a seemless integration. Also unless you're making this plugin solely for yourself you better believe that some peaceful day some user will show up yelling "why can't I change the icon color?" which even might be your future self.