Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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. mp5gosu
    3. Best
    M
    • Profile
    • Following 3
    • Followers 4
    • Topics 19
    • Posts 271
    • Best 79
    • Controversial 0
    • Groups 0

    Best posts made by mp5gosu

    • RE: Adding Custom Tree to TreeView.

      For custom nodes, check this thread here: https://developers.maxon.net/forum/topic/7651

      For using GeListNodes, etc. I currently don't have a minimal example. But let me try to bump you in the right direction.

      The TreeViewCustomGui uses a root object. This root is so to say a "container" that holds your list structure. This can be anything - you are then responsible to handle all the actions within the TreeViewFunctions, like GetNext(), GetDown() and so on. It is entirely up to you what you deliver to these functions. This level of abstraction comes with great flexibility.

      If you want to go for GeListNode, the following may work for you:
      Create a GeListHead - this is your root.
      Fill this root with GeListNodes as you desire.
      Then, hand the root over to your TreeViewCustomGui via SetRoot()
      And now, in the TreeViewFunctions, all you have to do is handle the nodes.

      So, if you can go a bit into detail, we should be able to pinpoint a solution.

      If you have any questions, I'll be happy to help. 🙂

      edit: By the way, you may want to start with BaseList2D instead of GeListNode since it already has SetName() / GetName() implemented and also supports selection bits. This is a bit easier to start off if you want to experiment.

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Move an object in hierarchy

      Hi, you have to write an own routine for that. I was writing this one a while ago:

      /**
       * @brief Moves all children of srcObj to tgtObj. Adds Undos.
       * @param srcObj The source object
       * @param tgtObj The target object
       */
      inline void g_MoveChildren(BaseObject* srcObj, BaseObject* tgtObj)
      {
      	if (!srcObj)
      		return;
      
      	auto doc = srcObj->GetDocument();
      	if (!doc)
      		return;
      
      	auto child = srcObj->GetDown();
      
      	while (child)
      	{
      		const auto temp = child->GetNext();
      		doc->AddUndo(UNDOTYPE::CHANGE, child);
      		child->Remove();
      		child->InsertUnderLast(tgtObj);
      		child = temp;
      	}
      }
      

      For further information about hierarchy manipulation, see https://developers.maxon.net/docs/cpp/2023_2/page_manual_gelistnode.html#page_manual_gelistnode_lists_edit

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Creating a Circle (spline) with varying number of points.

      You may also want to take a look at the official Cinema 4D SDK for an example of a circle object: https://github.com/PluginCafe/cinema4d_cpp_sdk_extended/blob/master/plugins/cinema4dsdk/source/object/circle.cpp

      Though it's C++, the algorithm should be easily adaptable.

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Which message do I receive when a command plugin dialog is closed?

      You can simply implement AskClose(): https://developers.maxon.net/docs/py/2023_2/modules/c4d.gui/GeDialog/index.html?highlight=askclose#GeDialog.AskClose

      Or even DestroyWindow() etc.

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: get lamp attributes?

      In Python, it's actually more convenient. You simply access them like this:
      Example is a cube, we want its X-size:
      Cube[c4d.PRIM_CUBE_LEN,c4d.VECTOR_X]
      You can simply drag an object's parameter into the command line of the console or the console itself. It then shows you the parameter names.
      That is the most simple and easiest way.
      However, that might not always work depending on what you want to read, so you have to use BaseContainer or GetParameter() as well.

      Oh and may I kindly ask you for tagging this thread correctly? It makes it easier to search the forums, so other users can benefit from your question.
      https://developers.maxon.net/forum/topic/10953/how-to-post-questions

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Python: Selection tag

      SelectionsTags return BaseSelects.
      You can then iterate over all polygons of your object and select those, that are contained in a BaseSelect.

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Save variables during current session (until C4D is closed)

      In addition to @m_adam's answer, you can use GetWorldPluginData() to save variables. Those even do exist after restarting Cinema 4D. You can clear them on application exit.

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Dealing with Symbolcache

      'open' or any other pure python function needs to be decoded as utf8.

      See hint here: https://developers.maxon.net/docs/py/2023_2/modules/c4d.storage/index.html?highlight=loaddialog#c4d.storage.LoadDialog

      Edit: a little late. 🙂

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Simulating a Scrub in the Timeline?

      You may want to try ExecutePasses() - that command will animate the current frame of the document and therefore works like scrubbing the timeline.

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: How to change the EXR compression method via python

      Oh yes, you are right. The SDK example doesn't work at all.
      Problem is, maxon.Id is wrong. maxon.InternedId would be the correct way for setting the save options. Here's the correct code:

      """
      Copyright: MAXON Computer GmbH
      Author: Maxime Adam
      Description:
          - Configures OpenEXR output render format with SetImageSettingsDictionary() then reads these with GetImageSettingsDictionary().
      Class/method highlighted:
          - c4d.bitmaps.SetImageSettingsDictionary()
          - c4d.bitmaps.GetImageSettingsDictionary()
      Compatible:
          - Win / Mac
          - R20, R21, S22, R23
      """
      import c4d
      import maxon
      
      
      def main():
          # Retrieves render data and its container
          renderData = doc.GetActiveRenderData()
          bc = renderData.GetDataInstance()
      
          # Gets image filters options
          saveOptions = bc.GetContainerInstance(c4d.RDATA_SAVEOPTIONS)
      
          # Sets OpenEXR output format
          bc[c4d.RDATA_FORMAT] = c4d.FILTER_EXR
      
          # Defines OpenEXR settings
          compressionmethodID = maxon.InternedId('net.maxon.mediasession.openexr.export.compressionmethod')
          halffloatID = maxon.InternedId('net.maxon.mediasession.openexr.export.halffloat')
          layernumberingID = maxon.InternedId('net.maxon.mediasession.openexr.export.layernumbering')
      
          # Configures OpenEXR format options with a maxon.DataDictionary
          exportSettings = maxon.DataDictionary()
          exportSettings.Set(compressionmethodID, maxon.Id("rle"))
          exportSettings.Set(halffloatID, True)
          exportSettings.Set(layernumberingID, True)
      
          # Stores settings in render data container
          c4d.bitmaps.SetImageSettingsDictionary(exportSettings, saveOptions, c4d.FILTER_EXR)
      
          # Pushes an update event to Cinema 4D
          c4d.EventAdd()
      
          # Retrieves OpenEXR images settings
          settings = c4d.bitmaps.GetImageSettingsDictionary(saveOptions, c4d.FILTER_EXR)
      
          # Reads and prints OpenEXR format options
          print("openexr.export.compressionmethod: " + str(settings.Get(compressionmethodID)))
          print("openexr.export.halffloat: " + str(settings.Get(halffloatID)))
          print("openexr.export.layernumbering: " + str(settings.Get(layernumberingID)))
      
      
      if __name__ == '__main__':
          main()
      
      posted in Cineware SDK
      M
      mp5gosu
    • RE: Looking for teamrender R15.064

      This does not belong here. This site is about developing plugins and the SDK in general.
      You may want to visit the support website

      By the way, if you own C4D R15, you already have TeamRender available. Just run your installation disc on a node of your choice and select TeamRender Client.

      posted in General Talk
      M
      mp5gosu
    • RE: Null characters in txt file (ascii - utf?)

      https://developers.maxon.net/docs/cpp/2023_2/page_manual_basefile.html#page_manual_basefile_byte_access

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: How to Generate Dynamic Functions?

      I modified your code to dynamically react to IDs. (Btw, it's now a script for simple demonstration).
      edit: Actually, this is just shifting the problem. There's no way in python I know of to bind functions directly. (Wouldn't make sense on dynamically added Gadgets anyways, imho.)

      import c4d
      from c4d import gui
      PLUGIN_ID = 1450011099
      
      # Based from Pim Grooff's code 
      # 
      def print_me(id): print id class MyDialog(gui.GeDialog): def InitValues(self): self.newfieldindex = 0 return True def CreateLayout(self): self.SetTitle("Add/Remove Enable/Disable Dialog") self.GroupBegin(id=1002, flags=c4d.BFH_MASK, cols=2) self.AddButton(1021, c4d.BFV_MASK, initw=145, name="Add") self.AddButton(1022, c4d.BFV_MASK, initw=145, name="Remove") self.GroupEnd() self.GroupBegin(id=1030, flags=c4d.BFH_MASK, cols=1) self.GroupEnd() return True def Command (self, id ,msg): if (id==1021): self.LayoutFlushGroup(id=1030) self.newfieldindex += 1 if (self.newfieldindex < 0): self.newfieldindex = 0 for newid in range(1,self.newfieldindex+1): button_id = newid + 1030 fieldname = "Add-" + str(newid) self.AddButton(button_id, c4d.BFV_MASK, initw=145, name=fieldname) self.LayoutChanged(id=1030) return True elif (id==1022): self.LayoutFlushGroup(id=1030) self.newfieldindex -= 1 if (self.newfieldindex < 0): self.newfieldindex = 0 for newid in range(1,self.newfieldindex+1): button_id = newid + 1030 fieldname = "Add-" + str(newid) self.AddButton(button_id, c4d.BFV_MASK, initw=145, name=fieldname) self.LayoutChanged(id=1030) return True else: print_me(id) return True if __name__ == "__main__": dlg = MyDialog() dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID)
      posted in General Talk
      M
      mp5gosu
    • RE: About PopupEditText and SendMail

      Just a dumb question: Did you include the maxon framework in your projectdefinition and did you run the project tool after that?

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Current C4D Object ID #'s and Type Descriptor string list --Where is one?

      There is one. Just take a look at your symbols.h file in resources directory.
      In prior versions it was called coffeesymbols.h

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Adding items to a LONG/CYCLE description container.

      You have to declare hdrs as a member variable. See 9.3.5: https://docs.python.org/2/tutorial/classes.html

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: GetLength compiler error

      You missed the braces (). 🙂
      GetLength -> GetLength()

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: get lamp attributes?

      Hello there and welcome to the plugincafe,

      since you didn't specify what language you want to use, here's a link to the C++ manual.
      You should go with GetParameter(): See here and here
      This blog post might also help you: [URL-REMOVED]

      Please consider adding appropriate tags to your post and flag it as a question. 🙂


      [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Global to Local pos

      You don't have to!

      There's also a function available: SetMg()

      I warmly suggest you to read the Matrix Fundamentals since it has been written to demystify the matrix math. It also has various code examples for all kinds of transformations, including your scenario.

      edit: Now that I think about your question: Do you want to move the parent with the child?

      posted in Cinema 4D SDK
      M
      mp5gosu
    • RE: Global to Local pos

      Sorry, got you slightly wrong then.

      Try this:

          m = op.GetMg() # get the object's matrix
          m.off = c4d.Vector(50) # modify the position
          op.SetMg(m) #set the modified matrix
          c4d.EventAdd() # update C4D
      

      This code simply moves the child, completely decoupled from its parent in absolute world coordinates.

      posted in Cinema 4D SDK
      M
      mp5gosu