Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login
    1. Maxon Developers Forum
    2. BretBays
    3. Topics
    B
    • Profile
    • Following 0
    • Followers 0
    • Topics 12
    • Posts 30
    • Best 0
    • Controversial 0
    • Groups 0

    Topics created by BretBays

    • B

      Gear Settings Icon Workflow

      Cinema 4D SDK
      • python • • BretBays
      3
      0
      Votes
      3
      Posts
      287
      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.

    • B

      ToolData Linkbox does not retain object when one is dragged in.

      Bugs
      • python • • BretBays
      7
      0
      Votes
      7
      Posts
      1.6k
      Views

      B

      Blah! Bummer. Seemed like a bug to me. I guess I will just convert this to a CommandData plugin and use GeDialog.

    • B

      Tool Tabs and foldable groups

      Cinema 4D SDK
      • python • • BretBays
      2
      0
      Votes
      2
      Posts
      369
      Views

      ferdinandF

      Hello @BretBays,

      Thank you for reaching out to us. Please provide code and a clear problem description as statements like `How do you create the tabs ... I tried X but it only creates tabs' are a bit confusing for us.

      There are two ways to create tab interfaces, one is via groups and the method GeDialog.TabGroupBegin and the other one is via CUSTOMGUI_QUICKTAB. We have a code example for it in Python here. The "tab-look" of descriptions, i.e., what you usually see in the Attribute Manager, is achieved with CUSTOMGUI_QUICKTAB. There is no group folding in dialogs anymore, this feature has been deprecated (we probably should update the docs).

      There is a difference between dialogs and descriptions. They use similar UI elements but they are not the same. Folding in descriptions is still supported, in dialogs not (but you can implement it yourself when you really need it). You should also be aware that there are ToolData and DescriptionToolData plugins. The former tool type uses dialogs to display its UI in the Attribute Manager, and the latter uses descriptions. Most tools these days in Cinema 4D are implemented as DescriptionToolData which leads to a distinctive look and set of features which are not trivial to emulate with a plain ToolData.

      ToolData is exposed in Python and C++, DescriptionToolData is only exposed in C++. My colleague @m_adam likes to point out whenever this subject comes up that the type SculptBrushToolData is exposed in Python (which is derived from DescriptionToolData) and that you can (ab)use it to implement a DescriptionToolData in Python. I never tried doing that and what consequences that would have (and neither did Maxime AFAIK). For my taste that would be way too hacky, and I would rather just live with the minor restrictions of ToolData plugin and its dialog based UI.

      Cheers,
      Ferdinand

    • B

      Question about organizing and utilizing custom python plugin libraries

      Cinema 4D SDK
      • python • • BretBays
      2
      0
      Votes
      2
      Posts
      336
      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

    • B

      Capture the dragging and release of a marker via python

      Cinema 4D SDK
      • 2024 python • • BretBays
      4
      0
      Votes
      4
      Posts
      566
      Views

      B

      Follow up but slightly unrelated question. If I have a GeDialog plugin with an edit field(for changing the Frame of a marker for example), is it possible to have it update while dragging vs on release? Is that some sort of CoreMessage thing? Right now I have a call inside of my Command function that basically says if the ID matches the edit field then set the marker frame. But I would like to be able to click and drag and see the marker's position move as I drag. Is that possible

    • B

      Foldable Groups in Python GeDialog

      Cinema 4D SDK
      • python 2024 • • BretBays
      5
      0
      Votes
      5
      Posts
      714
      Views

      i_mazlovI

      Hi @BretBays,

      Sorry for the delayed answer.

      Depending on how you picture the final look of your gui and how complex the behavior you'd like to have there, the means can be different.

      There's no easy way to achieve the same look as with "Freeze Transform" inside GeDialog. The suggested way would be to implement the logic manually and hide/show content by the button or a bitmap button. Such approach is demonstrated in the following examples:

      gedialog_menu_hide_content_r15.py that's pointed out by @Dunhou shows how to hide/show content customgui_quicktab_r19.py shows how to organize switch between your data using tab buttons

      If you really want to have the exact same look as foldable groups in the Description context, you could probably try drawing your layout with the DescriptionCustomGui that is capable of that (c++ example). However, I personally don't think this approach is worth the effort.

      Cheers,
      Ilia

    • B

      How to create python plugin in 2024?

      Cinema 4D SDK
      • 2024 • • BretBays
      6
      0
      Votes
      6
      Posts
      930
      Views

      B

      @ThomasB said in How to create python plugin in 2024?:

      Yes, download the SDK and study the examples.
      I wrote my own software that allows me to simply select the type of plugin I want to create, enter the plugin ID and the plugin name. The program then creates the folder structure, all files with the correct content and the correct name automatically...that was the first thing I did because it is always extremely tedious.
      This then takes 10 seconds and I have a finished blueprint. Then I can start programming straight away.
      I usually make the Gui first using UserData to roughly create the design and then I write it down in the resfile in no time at all. It's relatively quick and even fun and you gradually grow into it, it emerges little by little.....

      Basically it wouldn't be a problem to write a script that writes the UserData interface into a Res, header and string file, I already have an idea for that... That would actually be easy to do.
      I'll get to it when I'm done with my update... and then maybe make it available to the community... However, a similar one is already there, but I can't remember where.

      Greetings
      Tom

      Yeah, that sounds cool. The ui stuff you're mentioning was very similar to how the old ResEdit plugin worked. the source code is on gitHub, but I don't know how to compile C++ plugins.

      But I guess there is nothing there. This stems from me copying one of the examples from the Python SDK and trying to make it my own. It hasn't been very intuitive for me, which is why I asked because I figured I must have been missing something, but it seems I am not.

    • B

      Python Weight Painting Brush Plugin Questions

      Cinema 4D SDK
      • python 2024 • • BretBays
      2
      0
      Votes
      2
      Posts
      406
      Views

      M

      Hi @BretBays this is correct, if you want to make a Brush the easiest way is to register a SculptBrushToolData , you can find examples in Python in Github or in C++ in Github.

      SculptBrushToolData is derived from DescriptionToolData, meaning they can have a description visible in the attribute manager and therefor you can add your own checkbox if needed.

      Cheers,
      Maxime.

    • B

      [PYTHON] How to properly set the toggle of viewport solo

      Cinema 4D SDK
      • python 2024 2023 s26 • • BretBays
      3
      0
      Votes
      3
      Posts
      556
      Views

      B

      In the past I have refrained from CallCommands and CallButtons because they used to add to the undo queue or did. But I suppose in this instance I can just do it for thise purpose.

    • B

      Proper way to bake deformed mesh after adjusting joints.

      Cinema 4D SDK
      • python • • BretBays
      2
      0
      Votes
      2
      Posts
      530
      Views

      ferdinandF

      Hello @BretBays,

      Thank you for reaching out to us. Your posting does not contain an explicit question; there is no question mark in it. There is an implied question of us implementing what you describe, but the MAXON SDK group cannot do that, implement feature descriptions provided by users. I would recommend having a look at our support guidelines regarding asking good technical questions and the scope of support.

      About your Question

      If you want to CTSO, just CTSO the object or join it, we have examples for both cases in the modeling commands section of the Python examples. The problem with your function is also that it makes quite a few assumptions which do not always hold true, it for example assumes that the deform cache of something is always found directly on an object in the object manager (which is only true for editable polygon objects). What the script is calling 'direct copy' might also lead to results the user does not consider to be a copy.

      CSTO is the way to go to 'duplicate that deformed shape to a simple mesh with no deformer'. If the output is then not a singular object, you can join the output or a subset of it.

      Cheers,
      Ferdinand

    • B

      gui.ColorDialog() offers no options

      Cinema 4D SDK
      • • • BretBays
      3
      0
      Votes
      3
      Posts
      529
      Views

      M

      And I should have opened my eyes previously, but c4d.POPUP_BELOW shouldn't be used but instead color=gui.ColorDialog(0).

      I will improve the python documentation n this regards, for more information see the c++ doc about GeColorChoose.

      So this is not a bug.
      Cheers,
      Maxime.

    • B

      How to properly update and reset deform cache.

      Cinema 4D SDK
      • • • BretBays
      11
      0
      Votes
      11
      Posts
      1.8k
      Views

      M

      First of all, I'm sorry I simply forget your topic, so thanks for bumping it again.

      Regarding your question, I'm really not sure about what you want to achieve. So maybe try to explain what you want to achieve with simple step by step.

      Anyway, I will try to answers your question about how to retrieve the delta from a non-deformed geometry to a deformed geometry.
      Keep in mind that all points position retrieved by GetAllPoints() are local to the current object matrix, so doing a SetRelPos, on the object will most likely not affect the point position returned since it moves the whole object matrix.
      So here a quick example that properly retrieves the delta from a deformed object and its normal version.

      import c4d def main(): # Get the current world position allPtCurrentFrame = op.GetDeformCache().GetAllPoints() mgCurrentFrame = op.GetDeformCache().GetMg() # Move the mod +10 in Z in world position mod = doc.SearchObject('mod_1') modMat = mod.GetMg() modMat.off += c4d.Vector(0, 0, 10) mod.SetMg(modMat) # change the frame doc.SetTime(c4d.BaseTime(1, doc.GetFps())) buildflag = c4d.BUILDFLAGS_NONE if c4d.GetC4DVersion() > 20000 else c4d.BUILDFLAGS_0 doc.ExecutePasses(None, True, True, True, buildflag) # Get the next world position allPtNextFrame = op.GetDeformCache().GetAllPoints() mgNextFrame = op.GetDeformCache().GetMg() # Calculate the difference in both local space and global space diffLocalSpace = [allPtNextFrame[ptID] - x for ptID, x in enumerate(allPtCurrentFrame)] diffGlobalSpace = [(allPtNextFrame[ptID] * mgNextFrame) - (x * mgCurrentFrame) for ptID, x in enumerate(allPtCurrentFrame)] # For each axes create a Vertex map componentNames = ["x", "y", "z"] for componentId, componentName in enumerate(componentNames): # First find the maximum delta for the current component maxLocalSpace = 1 maxGlobalSpace = 1 for ptLocal in diffLocalSpace: maxLocalSpace = max(maxLocalSpace, ptLocal[componentId]) for ptGlobal in diffGlobalSpace: maxGlobalSpace = max(maxGlobalSpace, ptGlobal[componentId]) # Normalize all of them from 0 to 1 normalizedLocal = [pt[componentId] / float(maxLocalSpace) for pt in diffLocalSpace] normalizedGlobal = [pt[componentId] / float(maxGlobalSpace) for pt in diffGlobalSpace] # Create Tag for local vMapLocal = op.MakeVariableTag(c4d.Tvertexmap, op.GetPointCount()) op.InsertTag(vMapLocal) vMapLocal.SetName("{0}_local".format(componentName)) vMapLocal.SetAllHighlevelData(normalizedLocal) # Create Tag for Global vMapGlobal = op.MakeVariableTag(c4d.Tvertexmap, op.GetPointCount()) op.InsertTag(vMapGlobal) vMapGlobal.SetName("{0}_global".format(componentName)) vMapGlobal.SetAllHighlevelData(normalizedGlobal) c4d.EventAdd() # Execute main() if __name__=='__main__': main()

      Cheers,
      Maxime.