The Maxon SDK Team is currently short staffed due to the winter holidays. No forum support is being provided between 15/12/2025 and 5/1/2026. For details see Maxon SDK 2025 Winter Holidays.
  • How to SetKeyframeSelection for Subfield

    2024 python
    5
    1
    0 Votes
    5 Posts
    844 Views
    F
    Thanks again.@i_mazlov I haven't studied C++ yet, but I'm glad to know that it's achievable with C++.
  • Export RSproxy with Python

    python
    4
    0 Votes
    4 Posts
    893 Views
    R
    Great, thank you both very much. That helped a lot and I got the export working!
  • How to Undo Switching Between Modes?

    windows 2024 python
    10
    0 Votes
    10 Posts
    2k Views
    B
    @ferdinand said in How to Undo Switching Between Modes?: Well, just move the code which switches the mode to the end of your code when it is only cosmetic anyways. As I said above, a sensible way to use SetMode is when you want to leave the user in a state where he or she can continue working right away. But you can then just run all your code, check if everything went fine and then set your code. Otherwise you never set the mode, and therefore also have nothing to revert. It's a matter of workflow. It's not simply for checking the code that it's working properly. It's about a workflow. The workflow in the example is Select some mesh components, run the command. It generates something for you and switches the mode for you. If you selected the wrong components, you'd undo and try it again. But the undo won't put you back in the component mode. The issue is that that part of the command is not undoable so it's does hinder the workflow just a bit. I'm not necessarily advocating that it should be undoable or anything like that, just explaining the reasoning in this example and the value if it were undoable.
  • How to simulate "Cappucino" behavior?

    windows python 2024
    5
    0 Votes
    5 Posts
    954 Views
    ferdinandF
    PS: I would test this on heavy scenes with a lot of animations, to see if you get at least one data point for each frame (or whatever value you would consider acceptable).
  • 0 Votes
    8 Posts
    1k Views
    i_mazlovI
    Hi @hoffwerr , Please check our Support Procedures about consolidating consequent answers in a single posting. Please also do not duplicate your threads! I assume this question was answered in your second thread: GetChildren into an InExcludeData. Cheers, Ilia
  • 0 Votes
    4 Posts
    947 Views
    i_mazlovI
    Hi @justinleduc , Great to hear your issue was resolved! Special thanks on sharing your solution with the community! Regarding compiling issues you had: Error C2440: <function-style-cast>: cannot convert from AutoAlloc<ColorProfile> to GeData The AutoAlloc wrapper is just a convenient wrapper for a raw pointer. Hence, to fix your issue you just had to dereference the pointer: CheckState(colorProfile); settings.SetData(BAKE_TEX_COLORPROFILE, GeData(*colorProfile)); Cheers, Ilia
  • Can I convert a BaseBitmap into a Image file in memory?

    windows python 2024
    3
    0 Votes
    3 Posts
    537 Views
    DunhouD
    Hey @ferdinand , oops, I have an impression of this topic and tried to recall it, but I couldn't find any keywords in my mind at the time. I must have gone crazy. And the key is the GetData(), I have no concept of file composition and did not realize that what is returned here is the data required for an image file. Thank you very much. Cheers~ DunHou
  • Python Api: Document Events

    python
    8
    0 Votes
    8 Posts
    2k Views
    ferdinandF
    Hey @paulgolter, yes, this is okay. What you should not do, is traverse the whole scene graph, i.e., every object, shader, material, scene hook, track, curve, key etc that are to be found in a scene; just to get hold of all cube objects for example. For performance critical operations, we should always only traverse what we really need . But you just traverse the objects which is totally fine. I personally would avoid recursion, passing around a list, and not using an iterator, as this all makes things slower. Especially recursion/function calls are not cheap in Python. For the next major release we added some premade scene traversal functions in Python. I have attached one of the functions which will be exposed below. But your function is probably fine too, this is all very nitpicky. You do not use full recursion which is the most important thing. Everything else is probably nerd-talk. Cheers, Ferdinand def IterateTree(node: c4d.GeListNode | None, yieldSiblings: bool = False, rewindToFirstSibling: bool = False, rewindToRoot: bool = False) -> typing.Iterator[c4d.GeListNode]: """Yields nodes that are hierarchically related to `node`. .. note:: This function walks a node tree in a purely iterative manner, which makes it fast and robust for medium to large trees. For small trees (<= 100 nodes) `RecurseTree` is slightly faster. This function is usually the faster and safer choice compared to `RecurseTree` as the performance gain for large trees is significant while the loss for small trees is negligible. .. note:: To also yield non-hierarchical relationships, use `RecurseGraph` instead. :param node: The root node to start iterating from. :type node: c4d.GeListNode or None :param yieldSiblings: Whether to yield the next siblings of the current node, defaults to `False`. :type yieldSiblings: bool, optional :param rewindToFirstSibling: Whether to rewind the node to its first sibling before the iteration is carried out, defaults to `False`. :type rewindToFirstSibling: bool, optional :param rewindToRoot: Whether to rewind the node to its root before the iteration is carried out, defaults to `False`. :type rewindToRoot: bool, optional :return: An iterator that yields the descendants of the passed `node`. :rtype: typing.Iterator[c4d.GeListNode] :raises RuntimeError: If the UUID of a node could not be retrieved. :Example: .. code-block:: python import c4d from mxutils import CheckType, IterateTree # For the object tree: # # A # |___B # | |___C # | |___D # | | |___E # | |___F # G # Find the object named "D" in the scene. d: c4d.BaseObject = CheckType(doc.FindObject("D")) # Will yield D and E. for node in IterateTree(d): print (node) # Will yield D, E, and F. But not C as we start out at D and #yieldSiblings only looks # downwards, at next siblings and not previous ones. for node in IterateTree(d, yieldSiblings=True): print (node) # Will yield C, D, E, and F. Because we rewind to the first sibling of D - which is C. for node in IterateTree(d, yieldSiblings=True, rewindToFirstSibling=True): print (node) # Will yield A, B, C, D, E, and F. But not G, as we do not yield siblings. for node in IterNodeTree(d, rewindToRoot=True): print (node) # Will always yield the whole tree, no matter where we start. for node in IterateTree(d, True, True, True): print (node) """ def iter(node: c4d.GeListNode) -> typing.Iterator[c4d.GeListNode]: """Iterates over the descendants of the passed `node`. """ # The visited nodes and the node to stop iteration at. visited: dict[bytes, c4d.GeListNode] = {} terminal: c4d.GeListNode = node # Walking a tree iteratively is faster for medium to large trees than a recursive or # semi-recursive traversal. See: https://developers.maxon.net/forum/topic/13684 while node: # We could use GeListNode.__hash__ here, but it turns out that it is much slower than # doing it manually with MAXON_CREATOR_ID (sic!). Probably because of the overhead of # __hash__ hashing the UUID into an integer? nodeUuid: bytes = bytes(node.FindUniqueID(c4d.MAXON_CREATOR_ID)) if nodeUuid is None: raise RuntimeError(f"Could not retrieve UUID for {node}.") # Yield the node when it has not been encountered before. if visited.get(nodeUuid) is None: yield node visited[nodeUuid] = True # Walk the graph in a depth first fashion. getDown: c4d.GeListNode | None = node.GetDown() getNext: c4d.GeListNode | None = node.GetNext() getDownUuid: bytes | None = getDown.FindUniqueID(c4d.MAXON_CREATOR_ID) if getDown else None if getDown and getDownUuid is None: raise RuntimeError(f"Could not retrieve UUID for {getDown}.") if getDown and visited.get(bytes(getDownUuid)) is None: node = getDown elif node == terminal: break elif getNext: node = getNext else: node = node.GetUp() # --- End of iter() ---------------------------------------------------------------------------- if not isinstance(node, c4d.GeListNode): return # Set the starting node. # if rewindToRoot: # node = GetRootNode(node) # if rewindToFirstSibling: # node = GetFirstSiblingNode(node) # Traverse the hierarchy. while node: yield from iter(node) if not yieldSiblings: return node = node.GetNext()
  • How to change the value here using python

    2024 python
    8
    1
    0 Votes
    8 Posts
    1k Views
    F
    @ferdinand Thanks so much for such a detailed response. Learned a lot. My problem is solved. Thank you very much.
  • Hide the illumination group in node materials

    c++
    2
    0 Votes
    2 Posts
    526 Views
    ferdinandF
    Hey @bojidar, Thank you for reaching out to us. I assume you are talking about NodeMaterial cases, i.e., a material realized by the Nodes API. [image: 1722273375699-a78c9ce8-3a6c-4903-8428-625e0f8add14-image.png] Something like a NodeMaterial does not actually exist under the hood. A NodeMaterial is just a modified Material (i.e., the type Mmaterial) where pretty much everything except for the Viewport (and previously Illumination) tab is being hidden. This is done by us overriding GetDDescription in Material. By default not the whole illumination tab is hidden, but only everything below the check box "Portal" (don't ask me why). I just had a look: And for Redshift we recently added a section in Material::GetDescription where we check for a material being part of the Redshift node space and then hide the full tab. Since third parties do not own/overwrite Material, their node material then looks different, without them being able to change that (here at the example of V-Ray): [image: 1722273065911-e03ce790-eb53-43dc-a604-ddfe5a7bace6-image.png] For me it looks a bit like that we unintentionally left that group there. Maybe physical render node materials were/are still using that? But at least I do not see a reason why light portals and polygon lights must be standardized in this manner (we hide that group except for physical). I would recommend reaching out to us with a mail and the request to remove that "feature", i.e., make this more a program management than a programming thing. I cannot guarantee that we will do this, as there might be some special material management reasons why this has been done, but the starting point would be to have a PM discussion. Cheers, Ferdinand
  • 0 Votes
    3 Posts
    529 Views
    kangddanK
    @ferdinand Thank you !
  • How to scale all objects in a scene at once?

    2
    0 Votes
    2 Posts
    645 Views
    ferdinandF
    Hello @j_vogel, 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: Asking Questions. About your First Question As lined out above, please follow our support procedures. Thread necromancy usually leads to problems, at least when that much time has passed, I have forked this thread. Please also follow our rules about Support Procedures: Asking Questions, in short, we do not answer "please implement this or that for me". The parameter DOCUMENT_DOCUNIT in a document is just something that is added to things like the coordinate manager, to set the unit and a multiplier for the numbers shown there. It will not scale the actual geometries (as it otherwise would be destructive) and therefore does not affect the view port. To scale all elements in the scene, you must scale all elements . You can use the command which we implemented for that, what is talked about above and which can be invoked with the button in the document scale settings. But you then have to use its UI, which is I guess not what you want. So, you would have write something like that yourself. But there is currently no premade scene traversal in Python which can be a bit daunting for beginners (will change with the next major release). Carrying out the scaling itself is not that hard, although this complexity can also vary based on the content. Since I know you have beta access: You can also pick the latest beta build, the traversal stuff is already in there. Cheers, Ferdinand Code """Demonstrates how to scale all objects in a scene by a given factor. """ import c4d SCALE_FACTOR: c4d.Vector = c4d.Vector(2) # Scale factor for the objects, we pick a uniform scale of 2. doc: c4d.documents.BaseDocument # The currently active document. def IterateTree(node: c4d.GeListNode, yieldSiblings: bool = False) -> c4d.GeListNode: """Iterates over all descendants of the given #node and optionally its next siblings. In the next major release, there will be (finally) built-in scene traversal functions in Python. The one to pick for this case would be `mxutils.IterateTree`. Its signature is compatible with what I did here. """ def iterate(node: c4d.GeListNode) -> c4d.GeListNode: if not node: return yield node for child in node.GetChildren(): yield from iterate(child) while node: yield from iterate(node) node = node.GetNext() if yieldSiblings else None def main() -> None: """Called by Cinema 4D when the script is being executed. """ # Iterate over all objects in the document and scale them. for node in IterateTree(doc.GetFirstObject(), yieldSiblings=True): node.SetMl(node.GetMl() * c4d.utils.MatrixScale(SCALE_FACTOR)) c4d.EventAdd() if __name__ == '__main__': main() edit: you should of course use the local and not global matrix, as you otherwise will scale things multiple times.
  • Importing pythonapi from ctypes freezes C4D

    s24 macos python
    7
    0 Votes
    7 Posts
    2k Views
    ferdinandF
    Hey @lasselauch, We are not able to reproduce this crash on an Intel, M1, or M3 MacBook with 2024.4.0. Please provide and submit a crash report when this is still a problem for you. I would also recommend reinstalling Cinema 4D to rule out that your installation was damaged. Cheers, Ferdinand
  • Adding image to GeDialog - Python Plugin/Script

    python
    8
    0 Votes
    8 Posts
    2k Views
    DunhouD
    @ferdinand fine for that, like I think, this is not perfect solution for this, thanks for your confirm! Cheers~ DunHou
  • Transform coordinates of a polygon's points

    5
    0 Votes
    5 Posts
    1k Views
    i_mazlovI
    Hi @SmetK, Please note that we have a great Matrix Manual with code samples. You can also check our github repository for the geometry examples, e.g. the Polygon Object example. For your further questions I kindly encourage you to create new thread and shape your posting according to how it's described in our Support Procedures: Asking Question. Cheers, Ilia
  • Importing/loading sound file to scene via Python

    python 2024 windows
    4
    1
    0 Votes
    4 Posts
    703 Views
    i_mazlovI
    Hi @ezeuz, Great to hear you've figured it out and thanks for sharing the solution with the community! Cheers, Ilia
  • Clearing the list of a ComboBox (Dropdown) - Python API

    python
    3
    0 Votes
    3 Posts
    754 Views
    E
    @ferdinand Thanks a ton again! Yeah that dynamic UI is indeed something that fits perfectly with my current case, and possibly some other features I want to implement. Tho, I will revisit it later once I get to creating an MVP for my plugin. So I will use FreeChildren() for now.
  • Memory Leak? How to fix loosing memory with python generator?

    python macos 2024
    5
    0 Votes
    5 Posts
    1k Views
    M
    Hi sorry for not answering this topic earlier, I finally found some time to investigate and sadly there is nothing you can do in your side, this memory leak is coming from the Illustrator Importer and can be big, since all the points and tangents of the file are leaking. A fix will be available in the next update. Thanks for the report ! Cheers, Maxime.
  • 0 Votes
    4 Posts
    1k Views
    S
    @ferdinand Just ran into the same problem. Thank you for the solution!
  • Populating a Bitmap Shader without a file

    c++
    10
    0 Votes
    10 Posts
    2k Views
    D
    Hey Ferdinand, thanks again for the quick reply. What we're going to do is basically have a "cache" location, as you said, where we will save the users' textures when they bake the stack. I would also prefer the approach you showed using the document's asset repository, but since the textures might be very heavy, it would probably lead to very large document sizes for a lot of users, especially if they use several textures/have several stacks with textures. I'm working on implementing solution 1.1, using the Message system to move things around. However, thank you very much for the code example, I will probably use something similar with other assets that are not as large as textures. Cheers, Daniel