• 0 Votes
    4 Posts
    571 Views
    D
    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 Question We have noted your feedback and we are aware of some of the shortcomings of the current API. Subtool and folder management are high on the list of the use cases we plan to cover in a future API update. At the moment though, we don't have a set date for releasing a new version of the API. Please, let us know if you identify more areas of improvement. Regards, Davide
  • c4d.RSCAMERAOBJECT_COLOR_CONTROLS_CURVE_RGB

    Cinema 4D SDK python 2026 c++
    3
    1
    0 Votes
    3 Posts
    78 Views
    lasselauchL
    Thank you @ferdinand for looking into this, as well as bumping the request to the RS developers. Any update on this would be appreciated! Thanks.
  • TreeView DropDown Menu

    Cinema 4D SDK
    5
    0 Votes
    5 Posts
    1k Views
    ferdinandF
    Hey, yes it is. The trick is c4d.LV_CHECKBOX_HIDE, the relevant bits happen in GetDropDownMenu. Cheers, Ferdinand I removed the command, you can directly run this in the script manager: import c4d PLUGIN_ID = 12345678 PLUGIN_NAME = "ListView Dropdown Prototype" ID_TREE_VIEW = 1000 ID_FILE_NAME = 1001 ID_IMPORT_OPTION = 1002 ID_IMPORT_OPTION_DEFAULT = 1100 ID_IMPORT_OPTION_HIGH = 1101 ID_IMPORT_OPTION_MEDIUM = 1102 ID_IMPORT_OPTION_LOW = 1103 dummyfile_list = ["hud.stp", "material_reference.wrl", "front_axle.stp", "body.wrl", "wheel_variant.stp"] class DummyFile: def __init__(self, file_name, import_option="Default"): self.file_name = file_name self.import_option = import_option class DummyFileListView(c4d.gui.TreeViewFunctions): def __init__(self, dialog): self.dialog = dialog self.files = [DummyFile(file_name) for file_name in dummyfile_list] def GetFirst(self, root, userdata): return self.files[0] if self.files else None def GetNext(self, root, userdata, dummy_file): current_index = self.files.index(dummy_file) next_index = current_index + 1 return self.files[next_index] if next_index < len(self.files) else None def GetDown(self, root, userdata, dummy_file): return None def GetId(self, root, userdata, dummy_file): return id(dummy_file) def GetName(self, root, userdata, dummy_file): return dummy_file.file_name def IsSelected(self, root, userdata, dummy_file): return False def GetColumnWidth(self, root, userdata, dummy_file, column_id, area): if column_id == ID_FILE_NAME: return area.DrawGetTextWidth(dummy_file.file_name) + 24 if column_id == ID_IMPORT_OPTION: return 120 return 96 def GetDropDownMenu(self, root, userdata, dummy_file, column_id, menu_info): if column_id != ID_IMPORT_OPTION: menu_info["state"] = c4d.LV_CHECKBOX_HIDE return if not dummy_file.file_name.lower().endswith(".stp"): menu_info["state"] = c4d.LV_CHECKBOX_HIDE return options = { ID_IMPORT_OPTION_DEFAULT: "Default", ID_IMPORT_OPTION_HIGH: "High", ID_IMPORT_OPTION_MEDIUM: "Medium", ID_IMPORT_OPTION_LOW: "Low", } for option_id, label in options.items(): menu_info["menu"].SetString(option_id, label) menu_info["entry"] = next( option_id for option_id, label in options.items() if label == dummy_file.import_option ) menu_info["state"] = c4d.LV_CHECKBOX_ENABLED def SetDropDownMenu(self, root, userdata, dummy_file, column_id, entry): if column_id != ID_IMPORT_OPTION: return #this is logical but does not do the trick .... if not dummy_file.file_name.lower().endswith(".stp"): return options = { ID_IMPORT_OPTION_DEFAULT: "Default", ID_IMPORT_OPTION_HIGH: "High", ID_IMPORT_OPTION_MEDIUM: "Medium", ID_IMPORT_OPTION_LOW: "Low", } dummy_file.import_option = options.get(entry, dummy_file.import_option) self.dialog.tree_view.Refresh() class ListViewDropdownDialog(c4d.gui.GeDialog): def __init__(self): self.tree_view = None self.file_list_view = DummyFileListView(self) def CreateLayout(self): self.SetTitle(PLUGIN_NAME) tree_view_settings = c4d.BaseContainer() tree_view_settings.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN) tree_view_settings.SetBool(c4d.TREEVIEW_HAS_HEADER, True) tree_view_settings.SetBool(c4d.TREEVIEW_HIDE_LINES, True) tree_view_settings.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) tree_view_settings.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True) tree_view_settings.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True) if c4d.GetC4DVersion() >= 24000: tree_view_settings.SetInt32(c4d.TREEVIEW_VERTICAL_SPACE, 4) self.tree_view = self.AddCustomGui(ID_TREE_VIEW, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 500, 220, tree_view_settings, ) if not self.tree_view: return False layout = c4d.BaseContainer() layout.SetLong(ID_FILE_NAME, c4d.LV_TREE) layout.SetLong(ID_IMPORT_OPTION, c4d.LV_DROPDOWN) self.tree_view.SetLayout(2, layout) self.tree_view.SetHeaderText(ID_FILE_NAME, "Dummy file") self.tree_view.SetHeaderText(ID_IMPORT_OPTION, "STP import option") self.tree_view.SetRoot(self.tree_view, self.file_list_view, None) return True def InitValues(self): self.tree_view.Refresh() return True if __name__ == "__main__": dialog = ListViewDropdownDialog() dialog.Open(c4d.DLG_TYPE_MODAL, 0, -1, -1, 500, 220)
  • Change render Space (Color Profile) - how?

    Cinema 4D SDK 2025 2026 python
    10
    2
    0 Votes
    10 Posts
    264 Views
    ferdinandF
    You likely have to call UpdateOcioColorSpaces, just follow the example. There is btw no guarantee at all that DOCUMENT_COLOR_MANAGEMENT entails a render space of ACEScg. That is just the default, the user could have changed that. I am also not sure what all that RDATA_IMAGECOLORPROFILE code is meant to do. It depends a bit on what your plugin does and what self.IsForceLinear is meant to express. Only so much: An OCIO document does not necessarily entail a bitmap with a non-linear color profile, and OCIO also does not mean that the bitmap has to be 32bit. You are however missing UNDOTYPE_PRIVATE_DOCUMENTDATA undo management for setting the color management.
  • MergeDocument() crash C4D

    Cinema 4D SDK python 2026
    11
    0 Votes
    11 Posts
    394 Views
    chuanzhenC
    @ferdinand Okay, I will handle the plugins and files at an appropriate time.Thanks reply
  • 0 Votes
    10 Posts
    386 Views
    chuanzhenC
    @ferdinand Thanks for your detailed explanation. Although the precision conversion leading to value changes is not an error, it is indeed not what we want in terms of the results. For example, when dealing with the weight of some points, using SetWeightMap() will update the weights of other points, resulting in numerical changes. Only using SetWeight() can at least ensure that the weights of unoperated points do not undergo numerical changes (but using SetWeight() must tolerate the print warnings outputted by the console)
  • Disable all animation in document

    Cinema 4D SDK python 2026 windows
    5
    0 Votes
    5 Posts
    211 Views
    C
    Hi, @ferdinand and @Anlv this is most awesome! All way beyond my capablities so thanks a lot for the scripts!
  • List of selected edges

    General Talk off-topic-question
    2
    0 Votes
    2 Posts
    120 Views
    ferdinandF
    Hey @Kantronin, you might want to look at geometry_polgyon_edges_2024.0.py, it should answer all your questions. The TLDR is: full-edge maps as you hint at in your posting do exist in Cinema via helper functions, but they are often also not very useful. Internally, Cinema is operating as any other DCC application with the concept of what is often called a "half-edge" data structure. So, when you have the two polygons A and B: a---b---e | A | B | d---c---f Which share an edge over the vertices b and c, this is actually two edges and not one, due to how normals work. For both polygons to have a normal facing in the same direction, they must have opposite winding orders, which means that the edge b-c is actually two edges: b->c and c->b. So, A could for example index the edge as bc, and B as cb. The example goes into more detail with this. Cheers, Ferdinand
  • 0 Votes
    3 Posts
    134 Views
    chuanzhenC
    @ferdinand Thanks for your detailed explanation and the implementation of the sorting function. It's very helpful!
  • 0 Votes
    3 Posts
    208 Views
    A
    Thanks Anlv It looks like its adding the emitter into a null is what's causing it. Fixed with deferred CallCommand(1062577) (no sub-id (1067510) silently no-ops). Emitter fields greys if the emitter/group are parented under the setup null or generator. Sibling placement below plugin object + rename works fine.
  • 0 Votes
    4 Posts
    300 Views
    ferdinandF
    There seems to be some solution, please stay tuned until the RS team has sorted out things. I will then update this topic.
  • Alembic Export to Unreal - RootUVs?

    Cinema 4D SDK 2024
    4
    0 Votes
    4 Posts
    209 Views
    ferdinandF
    What I meant was to use the Cineware Unreal bindings, but I am not sure if they support it. Going the export route is a big backwards when Cinema has specific bindings. https://www.maxon.net/en/cineware I will give the Unreal dev a bump when I see him again.
  • 1 Votes
    3 Posts
    181 Views
    AnlvA
    @ferdinand Thank you so much! I made some minor adjustments to the plugin, adding support for CTRL hotkey activation, which allows quick reloading of previously checked plugins that need to be reloaded without opening the window. As always, open source, and will continue to be open source. Download: Plugin Debug Manager v1.5.0.zip Cheers, Anlv
  • Adding an Icon to a GeDialog Menu Group

    Cinema 4D SDK python sdk windows
    13
    1
    0 Votes
    13 Posts
    2k Views
    M
    Yes I wanted submenu with Icon, thanks for Up to Date clarification.
  • 0 Votes
    16 Posts
    1k Views
    ferdinandF
    This is not common knowledge, otherwise I would have spotted that earlier. So, you are not really expected to know this as a third party dev. You can look at the geometry_caches_s26.py example and there at this line, under [2] I mention that the cache of that object is muted. But that is of course only very indirect information and not enough to deduce this. I think we also talked about it a couple of times on the forum. The flag BIT_CONTROLOBJECT is set on input objects of generators, e.g., the to be extruded spline of an Extrude object, the profile and rail spine of a Loft object, the to be cloned cube and sphere objects of a MoGraph cloner, etc. As shown in the caching example, Cinema will mute the caches of input objects. To be very formal, they are actually built but then again deleted. BIT_CONTROLOBJECT marks such input objects. Your light in that scene should not have that flag, as it is not the input for some generator. But it somehow got it anyway, there is probably somewhere a bug. For normal scene evaluation that bug is also not really a problem (because as you saw from your own test, the light still converted correctly when you inserted it on its own outside of caches). The problems start when that irregularly as BIT_CONTROLOBJECT marked object is part of a cache. 'Make Editable' then incorrectly collapses the cache. Not only does it not stop at nested generators which are incorrectly marked like this, it also seems to apply the cache muting logic for input objects (resulting in the empty null object instead of the content of the cache of the collapsed generator). I already told the relevant devs that I consider this borderline buggy but they do not seem very inclined to do anything about this. What is effectively missing somewhere in cache resolvement is the evaluation if the flag BIT_CONTROLOBJECT 'makes sense on an object'. That is of not so easy to do, as generator - input object relations can be quite complex in Cinema. Which is probably also why the modelling team does not want to touch this. Cheers, Ferdinand
  • Cache Proxy Tag

    Cinema 4D SDK 2025 c++ windows
    10
    0 Votes
    10 Posts
    1k Views
    DunhouD
    This is how I’ve implemented it at the moment, although users can’t drag and drop selection tags in the same way as with C4D’s built-in generator. Hope there are plans to expose the proxy tags. Thanks for tour time!
  • 0 Votes
    3 Posts
    197 Views
    ThomasBT
    @ferdinand Yes, thanks, that indirect answer is enough for me. I was mainly wondering whether a check performed on both the client and the server is robust enough, or if it could be bypassed using Python, for instance. I’m well aware that it can be cracked somehow. I’m also already using ExportLicenses() for my node-locking system in combination. Thanks a lot for your help.
  • 0 Votes
    17 Posts
    1k Views
    ferdinandF
    I tried with a Cube where the only way to change colour is to use the display colour in the basic tab. At first sight this doesn't cause the problem, but in fact it does. Yes, that was what I meant. Thanks for confirming. The issue likely already has vanished in the current alpha, because there I could not reproduce it. But in 2026.3.2 I can. What is a bit odd is that no one seems to have touched the relevant code in the last months. But that is something for the GUI team to figure out.
  • 0 Votes
    2 Posts
    351 Views
    ferdinandF
    Hello @leah.hayes, 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 It is a bit difficult to answer you first question, as it is multiple questions of which some are open ended, please have a look at Support Procedures: How to Ask Questions for future postings. Where is the Python code of the built-in character templates ... They are stored in {c4d installation folder}/library.zip/characters. Is there a supported way to extract or view a built-in template (for example through c4d.modules.character.builder.Template) so I can study how the auto-adjustment is implemented? I am not quite sure that I follow. All these rigs are just our standard CA component system decorated with some Xpresso and Python. Since there can be literally hundreds of nodes in a rig, I attached below a little helper script to scan for specific Python content or just the scripts in general that are embedded somewhere in the rig. Is there a public API entry point to trigger or implement this kind of auto-adjustment for other templates? That auto adjustment seems to be some kind of Python script which the authors of this rig provided. These CA rigs have been created by (technical) artists and not the members of the Maxon development team. See the print out below for details on the artist code for "auto-adjustment". Cheers, Ferdinand Result ==================================================================================================== Node: Character Component (Character Component) | Attribute: (2158, 130, 1022113) Value: import c4d from c4d import gui import c4d.modules.character as ca import c4d.utils as utils #Welcome to the world of Python def Bl2DIterator(bl2D): while bl2D: yield bl2D for bl2DChild in Bl2DIterator(bl2D.GetDown()): yield bl2DChild bl2D = bl2D.GetNext() def SearchInHierarchy(obj, name): allChildrenWithName = [bl2D for bl2D in Bl2DIterator(obj.GetDown()) if bl2D.GetName() == name] return allChildrenWithName[0] def ShowLayer(layersList, showName): for layer in layersList: layerName = layer[c4d.ID_BASELIST_NAME] if showName in layerName: layer[c4d.ID_LAYER_VIEW] = True layer[c4d.ID_LAYER_MANAGER] = True def HideLayer(layersList, hideName): for layer in layersList: layerName = layer[c4d.ID_BASELIST_NAME] if hideName in layerName: layer[c4d.ID_LAYER_VIEW] = False layer[c4d.ID_LAYER_MANAGER] = False def CharacterAnimateMode(characterObject): characterObject[c4d.ID_CA_CHARACTER_COMPONENT_HIGHLIGHT_OVER] = 4 characterObject[c4d.ID_CA_CHARACTER_COMPONENT_MOUSEOVER] = 0 characterObject[c4d.ID_CA_CHARACTER_COMPONENT_VISIBLE] = 2 characterObject[c4d.ID_CA_CHARACTER_OM_DISPLAY] = 5 characterObject[c4d.ID_CA_CHARACTER_LOCK_AM] = False def CharacterEditMode(characterObject): characterObject[c4d.ID_CA_CHARACTER_COMPONENT_HIGHLIGHT_OVER] = 3 characterObject[c4d.ID_CA_CHARACTER_COMPONENT_MOUSEOVER] = 4 characterObject[c4d.ID_CA_CHARACTER_COMPONENT_VISIBLE] = 3 characterObject[c4d.ID_CA_CHARACTER_OM_DISPLAY] = 1 characterObject[c4d.ID_CA_CHARACTER_LOCK_AM] = True def CharacterBindMode(characterObject): characterObject[c4d.ID_CA_CHARACTER_COMPONENT_HIGHLIGHT_OVER] = 4 characterObject[c4d.ID_CA_CHARACTER_COMPONENT_MOUSEOVER] = 4 characterObject[c4d.ID_CA_CHARACTER_COMPONENT_VISIBLE] = 1 characterObject[c4d.ID_CA_CHARACTER_OM_DISPLAY] = 5 characterObject[c4d.ID_CA_CHARACTER_LOCK_AM] = True def CatchEmAll(obj, stop, listy): if obj is None: return #Actions go here if obj.GetType()==1019362: listy.append(obj) if not stop: if obj.GetDown(): CatchEmAll(obj.GetDown(), stop, listy) if obj.GetNext(): CatchEmAll(obj.GetNext(), stop, listy) return listy def SetGlobalRotation(obj, rot): """ Please remember, Cinema 4D handles rotation in radians. Example for H=10, P=20, B=30: import c4d from c4d import utils #... hpb = c4d.Vector(utils.Rad(10), utils.Rad(20), utils.Rad(30)) SetGlobalRotation(obj, hpb) #object's rotation is 10, 20, 30 """ m = obj.GetMg() pos = m.off scale = c4d.Vector( m.v1.GetLength(), m.v2.GetLength(), m.v3.GetLength()) m = utils.HPBToMatrix(rot) m.off = pos m.v1 = m.v1.GetNormalized() * scale.x m.v2 = m.v2.GetNormalized() * scale.y m.v3 = m.v3.GetNormalized() * scale.z obj.SetMg(m) def SetGlobalScale(obj, scale): m = obj.GetMg() m.v1 = m.v1.GetNormalized() * scale.x m.v2 = m.v2.GetNormalized() * scale.y m.v3 = m.v3.GetNormalized() * scale.z obj.SetMg(m) def ModeChanged(): characterObject = charop.GetObject() #Turning Off the Annotation # Main function leftAnnotationTag = SearchInHierarchy(characterObject, "LeftLeg_bind").GetLastTag() print(leftAnnotationTag) if leftAnnotationTag.GetType() == c4d.Tannotation: leftAnnotationTag[c4d.ANNOTATIONTAG_VIEWPORT_SHOW] = False #Hiding the Rig's Layers root = doc.GetLayerObjectRoot() #Gets the layer manager layersList = root.GetChildren() #Get Layer list for layer in layersList: layerName = layer[c4d.ID_BASELIST_NAME] if "Mixamo_Rig" in layerName: layer[c4d.ID_LAYER_VIEW] = False layer[c4d.ID_LAYER_MANAGER] = False mixamoLayers = layer.GetChildren() for layer in mixamoLayers: layerName = layer[c4d.ID_BASELIST_NAME] if "Retarget_Hierarchy" in layerName or \ "ANIMDATA_Nulls" in layerName or \ "Control Hierarchy" in layerName: layer[c4d.ID_LAYER_VIEW] = False layer[c4d.ID_LAYER_MANAGER] = False masterControl = SearchInHierarchy(characterObject, "Master_con+") hips = SearchInHierarchy(characterObject, "Hips") if nmode==c4d.ID_CA_CHARACTER_MODE_BUILD or \ nmode==c4d.ID_CA_CHARACTER_MODE_ADJUST: CharacterEditMode(characterObject) if nmode==c4d.ID_CA_CHARACTER_MODE_BIND: CharacterBindMode(characterObject) if nmode==c4d.ID_CA_CHARACTER_MODE_ADJUST and omode==c4d.ID_CA_CHARACTER_MODE_BUILD: #Changed search method to only search in Character Object #hips=doc.SearchObject("Hips") #masterControl=doc.SearchObject("Master_con+") #added Namespace Code nameSpace=masterControl[c4d.ID_USERDATA,16] results=CatchEmAll(hips, hips.GetNext(), []) for result in results: mixamo=doc.SearchObject(nameSpace+result.GetName()) if mixamo: matR = result.GetMg() matM = mixamo.GetMg() matR.off = matM.off matR.v1 = matM.v1.GetNormalized() matR.v2 = matM.v2.GetNormalized() matR.v3 = matM.v3.GetNormalized() result.SetMg(matR) if result.GetName()=='Neck1': #neck=doc.SearchObject(nameSpace+'Neck') #head=doc.SearchObject(nameSpace+'Head') neck = SearchInHierarchy(characterObject, nameSpace+'Neck') head = SearchInHierarchy(characterObject, nameSpace+'Head') if head and neck: result.SetMg((neck.GetMg()+head.GetMg())/2) print("Auto-Adjustment Complete") #Turning On the Annotation if leftAnnotationTag.GetType() == c4d.Tannotation: leftAnnotationTag[c4d.ANNOTATIONTAG_VIEWPORT_SHOW] = True if omode==c4d.ID_CA_CHARACTER_MODE_ADJUST and nmode!=c4d.ID_CA_CHARACTER_MODE_BUILD: L_Leg=doc.SearchObject("Left_IK_parent_rot_algn") #L_Leg = charop.FindObject("Left_IK_parent_rot_algn") if L_Leg: conTag=L_Leg.GetFirstTag() conTag[c4d.EXPRESSION_ENABLE]=False R_Leg=doc.SearchObject("Right_IK_parent_rot_algn") #R_Leg = charop.FindObject("Right_IK_parent_rot_algn") if R_Leg: conTag=R_Leg.GetFirstTag() conTag[c4d.EXPRESSION_ENABLE]=False if nmode==c4d.ID_CA_CHARACTER_MODE_ANIMATE: CharacterAnimateMode(characterObject) doc.SetActiveObject(masterControl, c4d.SELECTION_NEW) c4d.EventAdd() Code """Scans the document for all nodes that have multi-line string parameters that contain the word "adjustment" (case-insensitive) and prints the node name, type, parameter ID, and value to the console. """ import c4d import mxutils doc: c4d.documents.BaseDocument def main() -> None: """ """ node: c4d.BaseList2D pid: c4d.DescID # Iterate over all objects and tags in the document that live outside of caches and within the # object branch of the document. for node in mxutils.RecurseGraph(doc.GetFirstObject(), yieldBranches=True, yieldHierarchy=True, branchFilter=[c4d.Obase, c4d.Tbase]): # Iterate over the description, i.e., parameters of the node. for data, pid, _ in node.GetDescription(c4d.DESCFLAGS_DESC_NONE): # The first level of this parameter is not of type string or does not use the # multi-line string GUI, so we skip it. if pid[0].dtype != c4d.DTYPE_STRING or data[c4d.DESC_CUSTOMGUI] != c4d.CUSTOMGUI_STRINGMULTI: continue # Try to read the value, the exception block is needed as not all parameter types are # accessible in Python (and this could be some kind of exotic multi level string data type). try: value: str | None = str(node[pid]).strip() if not isinstance(value, str) or not value: continue except Exception: continue # Check if the value contains the word "adjustment" (case-insensitive), if not, skip it. if "adjustment" not in value.lower(): continue # Print the match. print ("\n\n" + ("=" * 100)) print (f"Node: {node.GetName()} ({node.GetTypeName()}) | Attribute: {pid}\n\nValue:\n\n{value}") # For good measure, select the node and break the loop. (doc.SetActiveObject(node, c4d.SELECTION_NEW) if isinstance(node, c4d.BaseObject) else doc.SetActiveTag(node, c4d.SELECTION_NEW)) break c4d.EventAdd() if __name__ == '__main__': main()
  • TimeLine DopeSheet not update

    Moved Bugs 2026 python
    5
    0 Votes
    5 Posts
    818 Views
    ferdinandF
    Hey, good news, this is fixed in the upcoming hotfix (2026.3.2).