• Copy children to selection with GetClone()

    python 2024
    3
    0 Votes
    3 Posts
    664 Views
    John_DoJ
    Hi @ferdinand, thanks for the feedback, I've got it working with your suggestion. The method B was correct but the undo part was wrong ( the undo step was applied on the original objects instead of the new ones, thus leading to a mess when performing an undo). I also added the bit part to keep new objects folded in the OM. Here is the code : # CopyDeformers import c4d doc = c4d.documents.GetActiveDocument() def main(): doc.StartUndo() objs = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER) if len(objs) >= 2: # Get the last selected object active = objs.pop(-1) # Get the deformers deformers = [i for i in active.GetChildren()] # Copy deformers to selection if deformers: for o in objs: for d in deformers[::-1]: dcopy = d.GetClone(c4d.COPYFLAGS_NO_BITS) doc.InsertObject(dcopy, parent=o) doc.AddUndo(c4d.UNDOTYPE_NEW, dcopy) o.SetBit(c4d.BIT_MFOLD) doc.EndUndo() c4d.EventAdd() if __name__ == '__main__': main()
  • Create folder in Volume Builder

    windows python 2023
    3
    0 Votes
    3 Posts
    589 Views
    D
    hi @i_mazlov, thanks for the answer. good to know about this status / limitation. for my current case I found a solution without folders..
  • How to LoadDocument from string in memory? 🤔

    python
    3
    0 Votes
    3 Posts
    962 Views
    mikeudinM
    Cool! Thank you!
  • fieldlayer with variable tag

    windows python 2023
    2
    1
    0 Votes
    2 Posts
    418 Views
    D
    found the solution ... the corresponding type is called: FLweight
  • Plugins Search Path from Preferences

    python
    3
    0 Votes
    3 Posts
    673 Views
    merkvilsonM
    Thanks @ferdinand I wrote this little script for those who want to add one plugin path via the C4D script. I will update it later. It will NOT overwrite existing paths. Restart is required for instant result. import c4d import os import json def add_plugin_path(path, restart = False): if os.path.exists(path): new_path = path.replace("\\", "/") else: print("Path does not exists") return prefs_folder = c4d.storage.GeGetC4DPath(c4d.C4D_PATH_PREFS) prefs_path = os.path.dirname(prefs_folder) plugins_json_path = os.path.join(prefs_path, 'plugins.json') if os.path.exists(plugins_json_path): with open(plugins_json_path,'r',encoding="utf-8-sig") as plugins: plugins_json_raw = plugins.read() plugins_dict = json.loads(plugins_json_raw) content_dict = plugins_dict["content"]["_impl"]["_data"][1]["content"] # Check if the new path is already in Plugins Path for content_path in content_dict: if os.path.normpath(content_path["_0"]["_path"]) == os.path.normpath(new_path): print(f"'{new_path}' is already in Plugins Path.") return else: plugins_dict = { 'identification': 'plugins', 'content': { 'referenceDataType': 'net.maxon.interface.datadictionary-C', '_impl': { '_mode': 2, '_data': [ { 'dataType': 'net.maxon.datatype.id', 'content': 'searchPaths' }, { 'dataType': '(net.maxon.interface.url-C,bool)', 'isArray': True, 'content': []}]}}} # Create new path content new_content = { "_0": { "referenceIndex": len(plugins_dict["content"]["_impl"]["_data"][1]["content"]), "referenceDataType": "net.maxon.interface.url-C", "_scheme": "file", "_path": new_path, "_authority": {}, "_data": {} }, "_1": True } # Append the new path to the list of paths plugins_dict["content"]["_impl"]["_data"][1]["content"].append(new_content) # Convert the dictionary back to a JSON string updated_plugins_dict = json.dumps(plugins_dict, indent=4) # Write the updated dictionary back to a JSON file with open(plugins_json_path, 'w') as plugins_json: plugins_json.write(updated_plugins_dict) if restart: c4d.RestartMe() custom_path = r"/Path/To/Plugin/Directory/" add_plugin_path(path = custom_path, restart = False)
  • how to store/serialize custom data type?

    c++
    4
    0 Votes
    4 Posts
    715 Views
    ferdinandF
    Hey @aghiad322, as I said, classic API CustomDataType types (e.g., the "dots" example) realize their serialization via CustomDatatypeClass::Read and ::Write. The DotsDataClass example implements both methods to read and write the dots data. If you want things to be stored, e.g., your gradient, you will have to implement it there. E.g., it could look like this: Bool MyDataTypeClass::WriteData(const CustomDataType* t_d, HyperFile* hf) { // Cast the passed in data to your datatype. const MyDataType* const data = static_cast<const MyDataType*>(t_d); // Bail when #data is malformed, has no gradient. _gradient is a member of MyDataType and supposed // to be of type Gradient* just as in your case. if (!data || !data->_gradient) return false; // Wrap the dereferenced _gradient as a GeData instance. GeData geData; geData.SetCustomDataType(*data->_gradient); // Write your data into the hyper file and bail if it somehow fails. if (!hf->WriteGeData(geData)) return false; // Write other data members of your datatype. if (!hf->WriteInt32(data->_someInt32)) return false; if (!hf->WriteFloat(data->_someFloat)) return false; if (!hf->WriteBool(data->_someBool)) return false; return true; } Cheers, Ferdinand
  • 0 Votes
    2 Posts
    440 Views
    ferdinandF
    Hey @BretBays, Thank you for reaching out to us. You might want to have a look at the Python Libraries Manual. Since Cinema 4D 2024.0 there is also mxutils.LocalImportPath which automates injecting module paths and reloading such imported modules (I probably should update the Python libraries manual). The "flaw" of all these approaches is that while you still encrypt your plugins pyp file, the imported module(s) py file(s) will not and cannot be encrypted. You can either ship your common functions unencrypted or develop your plugin as a multi module solution (so that you do not have to replicate your code across plugins) and then package up the plugin into a singular file. There are some Python tools like pysconcat and pymerger which can help you with that. But you should be aware that these can fail when you have complex dependencies. You could also serve the py-cache of your modules, but that will not really stop anyone who wants to read your code. Cheers, Ferdinand
  • Sampling Redshift Materials

    2024 c++ macos
    3
    0 Votes
    3 Posts
    732 Views
    D
    Hi Ilia, At this point this seems a bit over my head, but it seems to be what I need, thanks! Dan
  • Clone orientation without a "Up Vector"

    windows c++ 2024
    8
    0 Votes
    8 Posts
    3k Views
    justinleducJ
    @ferdinand Oh wow! Thank you so much for letting me know about Keenan Crane, as I was not familiar with him. I am in awe of the exhaustive list of tools he and his lab have published. The Globally Optimal Direction Fields paper seems indeed to be exactly what I am looking for. I was also surprised to see that I had already skimmed the Youtube video of the paper back in December. Thank you so much @ferdinand for this invaluable piece of information. Time to dive in! Cheers!
  • 0 Votes
    6 Posts
    1k Views
    S
    Okay. I'll ask the support center
  • Encrypt .pyp file to .pypv with script or command line?

    2024 python
    4
    0 Votes
    4 Posts
    930 Views
    F
    Thank you, it works perfectly!
  • document bug | GeDialog.SetString flags mismatch

    python 2024
    2
    1
    0 Votes
    2 Posts
    382 Views
    ferdinandF
    Hey @JACK0319, Thank you for your issue report, I have fixed it and it will be shipped with the next release. Cheers, Ferdinand
  • Accessing Parameters of Filters in a Volume Builder

    windows python 2023
    3
    0 Votes
    3 Posts
    549 Views
    ferdinandF
    Hey @datamilch, Thank you for reaching out to us and answering your own question. In general we prefer it when topics do not get deleted, so that other users can benefit from a topic. You should also not be able to delete this topic anymore since more than three hours have passed since you posted and because your topic has replies. Cheers, Ferdinand
  • Start Cinema 4D, how to set Preference path

    windows
    6
    1
    0 Votes
    6 Posts
    1k Views
    R
    @ferdinand Understood. thank you
  • Title in dropdown menu

    python
    2
    1
    0 Votes
    2 Posts
    779 Views
    i_mazlovI
    Hello @manudin! 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 These static text separators are just normal separators with provided title. You can do this by assigning BaseContainer instead of boolean (please check the code snippet below). Cheers, Ilia import c4d from c4d import gui def EnhanceMainMenu(): menu = c4d.BaseContainer() menu.InsData(c4d.MENURESOURCE_SUBTITLE, "My Menu 1") menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(c4d.Ocube)) menu.InsData(c4d.MENURESOURCE_SEPARATOR, True); menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(c4d.Osphere)) m = c4d.BaseContainer() m.InsData(c4d.MENURESOURCE_SUBTITLE, "My Category") menu.InsData(c4d.MENURESOURCE_SEPARATOR, m) menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(c4d.Oplane)) mainMenu = gui.GetMenuResource("M_EDITOR") mainMenu.InsData(c4d.MENURESOURCE_STRING, menu) if c4d.threading.GeIsMainThreadAndNoDrawThread(): c4d.gui.UpdateMenus() if __name__ == "__main__": EnhanceMainMenu()
  • Is that possible to hide column (header) in TreeView?

    windows 2023 2024 python
    5
    1
    0 Votes
    5 Posts
    1k Views
    gheyretG
    @czt_306 It looks realy cool!
  • Expose cpp-registered datatype to python

    c++ python
    4
    0 Votes
    4 Posts
    791 Views
    ferdinandF
    Hey @aghiad322, please re-read my answer I have given above. You implement a custom data type in C++, your SplineVisDataType in splinevis.h. Then you reference that data type in a resource of a Python plugin (SPLINEVIS ANIMATION_CLONER_SPLVIS { ANIM OFF; };). You will not be able to interact with this parameter/data type in Python until you have ported it or use the other approach I have lined out above - decomposition/channels. As also lined out above, you will be never able to get-access a parameter with a custom data type you have implemented yourself in Python because C4DAtom.GetParameter hardcodes the casting/unpacking of data types to Python. Cheers, Ferdinand PS: And if you only want another way to display SplineData, you can also just write a custom GUI targeting that data type. There is no necessity to always write your own custom data type for a custom GUI, you can also target existing ones. You would then have to set the custom GUI to yours when you define a SPLINE element in a dialog or description resource
  • How can we get the default port of a GraphNode?

    windows python 2024
    7
    1
    0 Votes
    7 Posts
    2k Views
    DunhouD
    Hey @m_adam , Can we port this DataDescriptionDatabaseInterface in python in some up-coming versions? this would be handy for some converting progress, now if I want to convert data, I have to manually writhe to node id, it is worth an automatic solution and we already have this. Cheers~ DunHou
  • Prevent material preview update

    windows python 2023
    3
    0 Votes
    3 Posts
    821 Views
    D
    hi @ferdinand, thanks for the information. found a workaround, that is good enough so far. I use the 3d-gradient in texture space and transform the texture tag matrix as I need it. the change in color will not occur that often.
  • Set value of a fieldlayer parameter

    windows python 2023
    3
    1
    0 Votes
    3 Posts
    559 Views
    D
    hi @ferdinand, this solved it, thanks! I suspected, that I would have to write back the data, as in many other cases. but I didn't know how exactly. As for the executable code: will do so, next time! cheers Sebastian