• Using / copying object properties dialog

    python 2023
    5
    1
    0 Votes
    5 Posts
    748 Views
    P
    Thanks for the clear answer. I know the difference between description and dialog, but I was hoping I could re-use already defined description in a dialog. But I follow your advise and recreate the settings. Regards, Pim
  • description.SetParameter() Question

    r23 2023 python windows
    11
    0 Votes
    11 Posts
    2k Views
    ThomasBT
    @ferdinand At first I wanted to do it exactly like you recommended, but then I thought why, if you save 36 IDs, it's certainly more memory-efficient. And when you just rename it, you've already learned something again. Actually, I wanted to do it with separate IDs. But then I recognized that I need the exact same 3 parameters, just with other Labels. but since renaming was faster, I decided to do it. It's an update of the previous version of the plugin and it was easiest to just change the labels. I'll think about it, I've got time. Thank you because my English is not always the best, I sometimes find it difficult to read your texts. They are already very extensive in some cases. Good evening!
  • Defer Modifying Menus to the Main Thread

    python s26
    6
    0 Votes
    6 Posts
    2k Views
    alexandre.djA
    @ferdinand Just a quick update that using an event message to force update the view after creating the menus is working great. c4d.EventAdd(c4d.EVMSG_CHANGE)
  • Plugin Update use "disklevel" or new PluginID

    r23 python windows 2023
    3
    0 Votes
    3 Posts
    546 Views
    ThomasBT
    @ferdinand thank you very much
  • How to create Preference hierarchy child tree item

    python r23
    3
    1
    0 Votes
    3 Posts
    566 Views
    mikeudinM
    @ferdinand Thank you! I'll check it!
  • Quicktabs in dynamic prefs description

    5
    1
    0 Votes
    5 Posts
    958 Views
    a_blockA
    No worries. Thanks for trying.
  • 0 Votes
    2 Posts
    443 Views
    ferdinandF
    Hello @fkenned1, Welcome to the Plugin Café forum and the Cinema 4D development 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 Guidelines, as they line out details about the Maxon SDK Group support procedures. Of special importance are: Support Procedures: Scope of Support: Lines out the things we will do and what we will not do. Support Procedures: Confidential Data: Most questions should be accompanied by code but code cannot always be shared publicly. This section explains how to share code confidentially with Maxon. Forum Structure and Features: Lines out how the forum works. Structure of a Question: Lines out how to ask a good technical question. It is not mandatory to follow this exactly, but you follow the idea of keeping things short and mentioning your primary question in a clear manner. About your First Question Your question is a little bit ambiguous, and I am not quite sure what you want to be done here. To get something simple out of the way: Cinema 4D C4DAtom instances, the atomic type all classic API scene elements derive from, have parameters which are indexed by c4d.DescID keys. Cinema 4D does not have properties in its classic API model. I understood what you meant, just as an FYI. This is represented by the methods C4DAtom.GetParameter and .SetParameter. The methods GeListNode.__getitem__ and .__setitem__, i.e., the bracket syntax in Cube[c4d.PRIM_CUBE_SUBY], are just convenience wrappers around the C4DAtom methods. The parameter keys passed to these methods are internally always c4d.DescID, it is only the convenience methods __get/setitem__ which allow you to pass integers instead, e.g., write Cube[c4d.PRIM_CUBE_LEN,c4d.VECTOR_X] or Cube[1100, 1000] (both do the same). I went over the subject of parameter IDs in more detail here. The drag and drop behavior of the Python console is proprietary and not exposed, I also do not quite understand what you want to do with it inside a dialog. If you want to let a user reference an object in a dialog, as for example many objects do in Cinema 4D, you must use a BaseLink parameter. In dialogs you can do this with the CUSTOMGUI_LINKBOX custom gui. I have shown here how to do this. Letting a user reference a parameter in this manner is not possible. You could technically unpack parameter drag data (at least in C++, likely not in Python, have not checked though) to get hold of a dragged BaseList2D and traverse its description (possible in C++ and Python) of a node to figure out to which DescID for example the string "c4d.PRIM_CUBE_LEN, c4d.VECTOR_X" corresponds to. But I do not quite understand the purpose of all this? I am sure there is a less complicated way to achieve what you want to do. I would recommend sharing your code and explaining what you want to achieve on a high level, as the workflow you have in mind is either impossible or at least very labor intensive to implement. Cheers, Ferdinand
  • Python version suddenly reported as 3.1 in 2023.2

    sdk python 2023
    3
    1
    0 Votes
    3 Posts
    639 Views
    M
    Ok, thanks Ferdinand your clarification shed some light on my problem. I convert the version to a float which is the culprit ... import sys if sys.version_info < (3, 2): print("This Plugin requires at least Python 3.2") thank you
  • Can get Point-Index under the mouse pointer? (Py)

    python sdk
    3
    1
    0 Votes
    3 Posts
    668 Views
    ymoonY
    The mouse position is obtained as follows. msg[c4d.BFM_INPUT_X] --> GetEditorWindow() --> editor_x = win.Global2Local() --> mouse_x-abs(Editor_x) The problem of overlapping selection in GetNearestPoint() was solved by making a list of selected object. Thank you.
  • Github Example group_nodes_r26 is broken.

    sdk python 2023
    4
    1
    0 Votes
    4 Posts
    492 Views
    ferdinandF
    Hello @Dunhou, I noticed maxon api changed every version and almost the major part of sdk change log We are aware that this fact is disliked by especially technical artists. But the Nodes API is still under active development and probably will be for the intermediate foreseeable future. Some changes from time to time are therefore inevitable. But we usually do not just remove something, but first mark it as deprecated and then remove it one or two cycles later, giving third parties more time to adapt. For S26, GraphModelInterface::IsSelected in graph.h changed for example into this: [[deprecated("Use GraphModelHelper static functions")]] MAXON_METHOD Result<Bool> IsSelected(const GraphNode& node); The problem is that this information is not visible at all for Python developers and still could also be improved for C++. We are aware of the problem, and working on the quality of change notes is something we already did over the last cycles and are still doing. Mapping such information to Python is certainly something I would like to do, but my main focus was for now gathering C++ API change notes in a more consistent manner. For now, I would recommend having an eye on the C++ change notes as a Python developer. The color coded deprecated markup should make it fairly easy to find upcoming removals, see for example the 2023.2 C++ API change notes. We are still working on improving API change notes for C++ and Python, because we are aware that it is crucial to clearly communicate our intentions with an API. I for example would like to make such information more searchable or pull it into the relevant documentary units. I.e., pull change notes also into the class, method, etc. descriptions, which are the subject of change. But that will be very hard to do with our current solutions might therefore have to wait a bit. Cheers, Ferdinand
  • Interaction Tag - def message seems to not work

    4
    1
    0 Votes
    4 Posts
    620 Views
    ferdinandF
    Hey @Smolak, You must expose the ID as explained in the posting and shown in the second code listing. Forgot to do it in the second one. I have updated the listing. Cheers, Ferdinand
  • 0 Votes
    5 Posts
    1k Views
    ymoonY
    @ferdinand It Works. Thank You
  • CUSTOMGUI_QUICKTAB trigger twice when click

    sdk python 2023 windows
    3
    0 Votes
    3 Posts
    417 Views
    DunhouD
    @m_adam Thanks man! this @dataclasses.dataclass decorator is pretty handy , new knowledge incoming And maybe some similar bug I have seen before , but I don't remember what it is (and even didn't know it is a bug or my bad coding ) , if I met some similar bugs I will update the topic , but now let's hope it will be fixed next release . Thanks for your help again Cheers~
  • How to obtain all vertices of an object in C++.

    s26 c++ sdk
    3
    0 Votes
    3 Posts
    592 Views
    P
    @m_adam Thanks
  • EnhanceMainMenu Inconsistent results in different c4d versions

    2023 python
    3
    1
    0 Votes
    3 Posts
    449 Views
    chuanzhenC
    @i_mazlov Thanks
  • 0 Votes
    3 Posts
    637 Views
    B
    @i_mazlov Gotcha. Thanks. Works as expected.
  • Inserting items into dropbox to TreeView

    4
    1
    0 Votes
    4 Posts
    706 Views
    M
    Hi @simonator420 for this purpose you have to define GetDropDownMenu and SetDropDownMenu. GetDropDownMenu is called by Cinema 4D to retrieve the content of the menu to display from the menuInfo dictionary. For more information about this dictionary please have a look at TreeViewDropDownMenuInfo Dict. SetDropDownMenu is called by Cinema 4D when the user select a value from the dropdown. Find bellow an implementation example: def GetDropDownMenu(self, root, userdata, obj: Entry, lColumn, menuInfo): menuInfo["entry"] = 1001 # Select teh second entry menuInfo["menu"][1000] = "First Entry" menuInfo["menu"][1001] = "Second Entry" menuInfo["menu"][1002] = "ThirdEntry" menuInfo["state"] = int(menuInfo["state"]) # Workaround to not have warning in Cinema 4D. Will be fixed in the next C4D version. def SetDropDownMenu(self, root, userdata, obj, lColumn, entry): print(f"User selected the entry with the ID: {entry}") Finally note that due to an issue that will be fixed in the upcoming version of Cinema 4D, even if you do not change the state, you need to override it to an int value otherwise it will print an error in the console (this is not blocking but still). Cheers, Maxime.
  • MoGraph color tag access

    c++
    4
    0 Votes
    4 Posts
    842 Views
    M
    Hi @Aaron sorry I have to admit I totally overlooked your case. So Fracture Object is a bit special in how color is handled, and this is not as an usual mograph object, where there is Modata and an array of color. Instead each part is a different PolygonObject and the color is simply the color of the object (the one from the basic tab when you select a polygon object in the attribute manager). So with that said find bellow a code to read color. // Get the fracture object BaseObject* obj = doc->GetFirstObject(); if (!obj && obj->GetType() == 1036557) return false; // Retrieve the cache. The Cache of a fracture object consist of a null and a bunch of PolygonObject where // each PolygonObject represents a part of the fracture. BaseObject* rootObjCache = obj->GetCache(); if (!rootObjCache) return false; BaseObject* child = rootObjCache->GetDown(); Random randomGenerator = Random(); while (child) { // Read Color GeData data; child->GetParameter(DescID(ID_BASEOBJECT_COLOR), data, DESCFLAGS_GET::NONE); Vector color = data.GetVector(); ApplicationOutput("@"_s, color); // Write Color with new random value, note that we write the cache, meaning each new re-evaluation of the Fracture object will reset these changes Vector randomColor = Vector(randomGenerator.Get01(), randomGenerator.Get01(), randomGenerator.Get01()); child->SetParameter(DescLevel(ID_BASEOBJECT_COLOR), randomColor, DESCFLAGS_SET::NONE); // Get Next Polygon Object aka the next part from the fracture child = child->GetNext(); } Cheers, Maxime.
  • Rendering render queue on program startup

    Moved
    6
    0 Votes
    6 Posts
    885 Views
    Z
    Hi @karol_w! This is exactly what I am looking for, because Octane keeps crashing on me. Unfortunately, I am not very good with coding. Is there any chance you would share your plug-in? Or point me towards where to find resources to build that myself? Thank you very much!
  • GetActiveUVSet() returns None if multiple UVs are active?

    python
    4
    0 Votes
    4 Posts
    863 Views
    ferdinandF
    Hello @Gene, So far it's doing exactly what I need. Only issue I have is if I need to undo the script. I have to press the Undo button several times because C4D creates an undo state for every Tag/Object selection step in the script, instead of putting all of them under one undo state. I think this is a long-existing limitation of C4D's Undo system? Well, it depends a bit on what you would consider a "long-existing limitation", but you can consolidate multiple operations into a singular item in the undo-stack. The most relevant methods are BaseDocument.StartUndo, BaseDocument.EndUndo, and BaseDocument.AddUndo (there more undo related methods on BaseDocument). Cheers, Ferdinand """Demonstrates wrapping selecting all top-level objects in a document into one undo item. """ import c4d doc: c4d.documents.BaseDocument def main(): """ """ obj: c4d.BaseObject = doc.GetFirstObject() # Start an undo item in the undo stack. doc.StartUndo() while obj: # Add an operation to the undo item, most operations must be invoked BEFORE the actual # operation is carried out. The only exception is inserting new nodes, AddUndo must here # be called AFTER the operation. doc.AddUndo(c4d.UNDOTYPE_ACTIVATE, obj) doc.SetActiveObject( obj, c4d.SELECTION_NEW if obj == doc.GetFirstObject() else c4d.SELECTION_ADD) obj = obj.GetNext() # Close the item. doc.EndUndo() c4d.EventAdd() if __name__ == "__main__": main()