• Python script for keyframing node material geometry opacity

    python 2025
    4
    0 Votes
    4 Posts
    593 Views
    i_mazlovI
    Hi @mia-elisenberg, Thanks for reaching out to us! I must note that as per our Support Procedures we cannot debug your code. Hence, in your future postings I kindly ask you to try simplifying your code to a minimal viable example, which highlights your question. Regarding your question, creating keyframes for nodes can be a little trickier comparing to the ordinary objects, but the general data accessing scheme stays the same. @Dunhou has thankfully posted the simplified example for your question, which already shows crucial pieces of how one would access the CTrack, CCurve and CKey for the node port. (@Dunhou I won't get tired showing our appreciation in playing an active role in our community! ). Namely, you're expected to use GetBaseListForNode to get the BaseList2D element that corresponds to the node you have. Additionally, NimbusBaseInterface.GetDescID can be used to get the DescID of the port. After you have this information, the process of interacting with animation data isn't any different. Your can check the animation examples in our repository: Cinema-4D-Python-API-Examples/scripts/04_3d_concepts/scene_elements /animation. The only thing I'd like to point out here is handling color data. Namely, CKey is designed to operate with float values, but Opacity channel works with color data. Hence, you need to create a separate CTrack for each color channel. You basically do this by pushing your DescID one level further to access the elements of your color data. Please find small example below (based on the code shared by @Dunhou): descLevelsRGB: list[c4d.DescLevel] = [ c4d.DescLevel(c4d.COLOR_R, c4d.DTYPE_REAL, 0), c4d.DescLevel(c4d.COLOR_G, c4d.DTYPE_REAL, 0), c4d.DescLevel(c4d.COLOR_B, c4d.DTYPE_REAL, 0) ] opacityValue: list[float] = [0.55, 0.66, 0.77] # example data to store in the keyframe ctime: c4d.BaseTime = c4d.BaseTime(doc.GetTime().GetFrame(doc.GetFps()), doc.GetFps()) for opacityChannelDescLevel, opacityChannelValue in zip(descLevelsRGB, opacityValue): # Get opacity channel DescID and push it to access color channel channelDescID: c4d.DescID = nimbusRef.GetDescID(opacityPort.GetPath()) channelDescID.PushId(opacityChannelDescLevel) track: c4d.CTrack = c4d.CTrack(opacityPortBL2D, channelDescID) opacityPortBL2D.InsertTrackSorted(track) curve: c4d.CCurve = track.GetCurve() key = c4d.CKey() track.FillKey(doc, opacityPortBL2D, key) # this is optional key.SetValue(curve, opacityChannelValue) key.SetTime(curve, ctime) curve.InsertKey(key) Cheers, Ilia
  • How to get the attributes of rsramp node in c++?

    c++ 2025
    3
    0 Votes
    3 Posts
    486 Views
    F
    @ferdinand Thank you for the answer! The problem is solved after I try to find the child of the port according to your answer.
  • New Condition Naming in Attribute Manager

    c++ r25
    3
    1
    0 Votes
    3 Posts
    620 Views
    D
    Thank you so much! I couldn't ask for a more thorough response. Dan
  • Help Needed: Filtering Selected Edges by Length

    windows python 2025
    2
    0 Votes
    2 Posts
    509 Views
    ferdinandF
    Hello @myosis, 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 All the methods you list simply do not exist (neither in C++ nor in Python), see c4d.utils.Neighbor for the type overview. I therefore must assume that you are using an AI, like, for example, ChatGPT, which hallucinated these methods. Please note that we reserve the right to refuse support when confronted with undisclosed AI gibberish, especially for beginner content. Always state when you used an AI to generate code. Something such as an edge does not exist concretely in our API and many other APIs, i.e., other than for points and polygons, there is no explicit data type for edges which would be stored. Edges are defined implicitly by CPolygon. To filter a selection for edges of a certain length, you would have to convert edge indices to polygon and point indices and then measure the distance between the relevant points. Cheers, Ferdinand Result [image: 1737027755224-074e2ada-a9ce-45b4-800a-acf7e060941a-image-resized.png] Code """Deselects all edges in the edge selection of the active object whose edge length exceeds MAX_EDGE_LENGTH. Must be run as a Script Manager script with an editable polygon object selected. """ import c4d doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. MAX_EDGE_LENGTH: float = 25.0 # The maximum length of an edge before to be considered too long. MAX_EDGE_LENGTH_SQUARED: float = MAX_EDGE_LENGTH ** 2 # The square of `MAX_EDGE_LENGTH`. def main() -> None: """Called by Cinema 4D when the script is being executed. """ if not op or not op.IsInstanceOf(c4d.Opolygon): raise ValueError("The selected object is not a polygon object.") # Get the edge selection of the object and turn it into a list of selected edges indices. Also, # get the points and polygons of the object. selection: c4d.BaseSelect = op.GetEdgeS() selectedEdges: list[int] = [i for i in range(op.GetEdgeCount()) if selection.IsSelected(i)] points: list[c4d.Vector] = op.GetAllPoints() polygons: list[c4d.CPolygon] = op.GetAllPolygons() def getPointByIndex(poly: c4d.CPolygon, index: int) -> c4d.Vector: """Returns the point of the polygon at the given index. CPolygon has no index access, so we fix that here. """ if index == 0: return points[poly.a] elif index == 1: return points[poly.b] elif index == 2: return points[poly.c] elif index == 3: return points[poly.d] # Iterate over the edges and find the one's that are longer than MAX_EDGE_LENGTH. An edge index # is defined as: # # "The edges are indexed by 4 * polygon + edge where polygon is the polygon index and edge is # the edge index between 0 and 3." # # So, we must revert that here, then measure the edge length, and collect all too long edges. tooLongEdges: list[int] = [] for edgeIndex in selectedEdges: polygonIndex: int = edgeIndex // 4 edgeInPolygonIndex: int = edgeIndex % 4 poly: c4d.CPolygon = polygons[polygonIndex] pointA: c4d.Vector = getPointByIndex(poly, edgeInPolygonIndex) pointB: c4d.Vector = getPointByIndex(poly, (edgeInPolygonIndex + 1) % 4) # Getting the length of a vector is quite expensive, so we compare the squared lengths. edgeLengthSq: float = (pointA - pointB).GetLengthSquared() if edgeLengthSq > MAX_EDGE_LENGTH_SQUARED: tooLongEdges.append(edgeIndex) # Print the indices of the edges that are too long. print("The following edges are too long:", tooLongEdges) # Deselect all edges in the object's edge selection that are too long. for edgeIndex in tooLongEdges: selection.Deselect(edgeIndex) # Push an update event to Cinema 4D to redraw the object. c4d.EventAdd() if __name__ == '__main__': main()
  • How to add a tree view to a Description Resource?

    2025 python
    3
    1
    0 Votes
    3 Posts
    468 Views
    chuanzhenC
    @ferdinand Thank you for your detailed answer.
  • Get command information from command palette

    python 2025 2024 2023
    5
    1
    0 Votes
    5 Posts
    879 Views
    gheyretG
    I get it, thanks for your reply and keeping the idea. If there are any workarounds or alternative solutions in the meantime, please let me know. I look forward to any updates regarding this feature in the future. Cheers~
  • About Texture Paths in MergeDocument

    2025 python windows
    3
    0 Votes
    3 Posts
    534 Views
    R
    @i_mazlov I get it, thanks for your reply.
  • python script change Redshift setting

    python windows 2024
    6
    0 Votes
    6 Posts
    1k Views
    R
    @Dunhou @i_mazlov Thanks a lot.
  • Automatically execute python scripte

    python 2024 windows
    2
    0 Votes
    2 Posts
    325 Views
    M
    Hi @serco, there is multiple way to execute a script automatically when Cinema 4D is opened. Use python_init.py, this force you to add your script into the temp folder. Bu it can be done for a particular instance of a Cinema 4D or it can also be applied to all Cinema 4D versions that use a given python version. Implement a Plugin and react to PluginMessage various event are sent to Python, and you can hook into them to execute your code. This require to have a Python plugin loaded by Cinema 4D. Depending of your needs there is c4dpy which act as a Python Interpreter, where you can pass directly your Python file as an argument. Then again depending of your need you may be able to start what you want to do next. Cheers, Maxime.
  • SetJointResetState() Parameter interpretation error in py doc?

    python
    4
    1
    0 Votes
    4 Posts
    493 Views
    M
    Thanks a lot for reporting this kind of issue ! This is going to be fixed in the next update of the doc. Cheers, Maxime.
  • Making changes to the document through a websocket

    windows s24 c++
    6
    0 Votes
    6 Posts
    1k Views
    C
    @m_adam Thank you very much for your help in the last days! This worked as well as expected
  • Gear Settings Icon Workflow

    python
    3
    0 Votes
    3 Posts
    530 Views
    M
    Hi @BretBays Happy Christmas ! Thanks for getting back, and indeed PLUGINFLAG_COMMAND_OPTION_DIALOG is the way to go. Find an example in CommandData with Options Dialog - Docked command button Cheers, Maxime.
  • Unexpected "refresh" behavior when manipulating linked object

    2024 c++ windows
    10
    3
    0 Votes
    10 Posts
    2k Views
    H
    @ferdinand After a lot of time forced to work on other projects, I have looked further into this, and sent you an email. I hope you don't see it until after the holiday season.
  • WebSocket usage in C++

    c++ windows macos s24
    6
    1
    0 Votes
    6 Posts
    945 Views
    C
    Hi @m_adam, following your typescript example it worked now to connect! Thank you very much for your help Merry Christmas and a Happy New Year!
  • Get and Set any parameter with Tag

    2023 2024 2025 python
    3
    0 Votes
    3 Posts
    641 Views
    gheyretG
    Hi @i_mazlov I can't use C++ at the moment, so I thought I'd try MultilineEditText for my purposes. I looked for This post in the forum and now I have some ideas. Thank you for your reply! Cheers~
  • 0 Votes
    2 Posts
    403 Views
    i_mazlovI
    Hi @shahir-zaman , 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 Assuming that what you're trying to achieve is to toggle the "UV Grid" option [image: 1734354534219-d09d5b8d-51a2-4a6a-9618-90b2dbcc6638-image.png] You effectively have two options: The easiest one is to execute CallCommand(170776) (you can find the command ID in the Script Log) The more involved but also more flexible way is to find the UV settings scenehook and go through all its branches (or may be not all of them, depending on what specifically you want to achieve). Please find the C++ and Python code snippets below. Cheers, Ilia C++ commanddata execute function code snippet: Bool MyCommandData::Execute(BaseDocument* doc, GeDialog* parentManager) { const Int32 ID_UV_SETTINGS_HOOK = 1053309; if (!doc) return true; BaseSceneHook* sceneHook = static_cast<BaseSceneHook*>(doc->FindSceneHook(ID_UV_SETTINGS_HOOK)); if (!sceneHook) return true; maxon::BufferedBaseArray<BranchInfo, 20> infos; sceneHook->GetBranchInfo(infos, GETBRANCHINFO::NONE) iferr_ignore("GetBranchInfo"); for (BranchInfo& info : infos) { if (info.name != "UVSettingsBranch"_s) continue; GeListNode* viewSettings = info.head->GetFirst(); while (viewSettings) { GeData value; viewSettings->GetParameter(CreateDescID(UV_SETTINGS_FILTER_SHOW_GRID), value, DESCFLAGS_GET::NONE); Bool valueBool = value.GetBool(); value = {!valueBool}; viewSettings->SetParameter(CreateDescID(UV_SETTINGS_FILTER_SHOW_GRID), value, DESCFLAGS_SET::NONE); viewSettings = viewSettings->GetNext(); } } EventAdd(); return true; } Python script code snippet (special thanks to @m_adam on this one): import c4d def main() -> None: sh = doc.FindSceneHook(1053309) for branch in sh.GetBranchInfo(): if branch["name"] != "UVSettingsBranch": continue viewSettings = branch["head"].GetFirst() while viewSettings: viewSettings[c4d.UV_SETTINGS_FILTER_SHOW_GRID] = not viewSettings[c4d.UV_SETTINGS_FILTER_SHOW_GRID] viewSettings = viewSettings.GetNext() c4d.EventAdd() if __name__ == '__main__': main()
  • Is there anyway to get/set the Place tool?

    Moved programming
    2
    1
    0 Votes
    2 Posts
    519 Views
    M
    Hi sadly this is not possible. I've reached to responsible team to make them aware about it. Cheers, Maxime.
  • Set UVWs for Ngons?

    s26 python
    4
    1
    0 Votes
    4 Posts
    747 Views
    E
    @ferdinand I figured this issue out so you can mark this as solved/closed. Thank you.
  • SubContainers and Symbol ranges

    c++
    5
    0 Votes
    5 Posts
    566 Views
    ferdinandF
    Hey @ECHekman, I assume you are looking here for some kind of approval from my side? That looks fine, but it is hard to give a concrete assessment with mock code. But as lined out above, there is little which can go wrong here. Splitting up your data into sub-containers could help with access times when you plan to add lots of 'attributes' and 'pins'. So, it is good that you do that. And shifting your application IDs into lower ranges for Cinema 4D is probably not technically necessary but will lead to more 'natural' IDs. I cannot really see much going wrong here. The only thing which is not so nice, is the unsafe C-style cast in BaseContainer *data = ((BaseShader*)node)->GetDataInstance();. We recommend using static_cast for safe casts and reinterpret_cast for casts which are explicitly meant to be unsafe. Cheers, Ferdinand
  • Easy Way to Set and Get parameter Values

    Moved programming
    5
    2
    0 Votes
    5 Posts
    907 Views
    G
    Thanks for your answer.