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

    Proud to announce the c4dtools library!

    PYTHON Development
    0
    14
    1.8k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 06/01/2013 at 11:07, xxxxxxxx wrote:

      hey nikklas,

      i think that it is a great idea to create some sort of c4d related python libs. any form symbol
      management is really welcome  i think, it kind of sucks, that you have always do the work twice
      currently. however, i am not sure if i really want to wrap the plugin registration. loosing pretty 
      much control for just 2-3 lines here.

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 07/01/2013 at 07:08, xxxxxxxx wrote:

        Hello Niklas.
        Thank you for lib!

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 07/01/2013 at 08:24, xxxxxxxx wrote:

          Hello Ferdinand,

          Thanks for your feedback. I've been experimenting very much until I found this way of loading
          and using the symbols. It's quite usable IMHO now.

          If you don't want to loose this control, you do not have to use the plugin class. I was tired
          of writing the registration code over and over again, (including loading the bitmap, etc.). You could
          also overwrite the c4dtools.plugins.Command.register() function.

          You wouldn't have needed to remove the code you have posted. I've already put the
          console-flushing and container-printing function into the module, thanks for the ideas. They'll
          be included in the next commit, but in the development branch. The master-branch will be updated
          as major changes come up.

          Best,
          Niklas

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 07/01/2013 at 09:25, xxxxxxxx wrote:

            hey,

            i am to lazzy to write a wall of text, so just a list:

            Register()

            1. return the results of the RegisterXyzData() methods in some form.

            2. add a member which let you print some text to the console when RegisterXyzData() is True.

            3. provide a reference to the actual instance of the registered plugin class.

            Symbols :

            1. it would be nice if the text length required to call a member of res would be shorter.
            i am currently using a module which is just called con, where all my constants are sitting.
            so it would be cool if it would be possible just to type res.IDC_MYELEMENTID.

            2. i really like the feature that you can add manually constants. at least i am reading
            string_2 = res.string.IDC_MYSTRING_2("Peter") in that way (or is it a dict search value) ?

            3. another cool feature would be an automatic attribute initialization (InitAttr()) for ressource
            based GUIs by parsing the res file and choosing the correct attribute type.

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 07/01/2013 at 10:18, xxxxxxxx wrote:

              Hi Ferdinand,

              Register

              @1: Don't get it.
              @2: You can overwrite the register() method for this.

              class MyCommand(c4dtools.plugins.Command) :
                    # ...
                   def register(self) :
                        if super(MyCommand, self).register() :
                            print "Plugin Successfully registered."
                              return True
                        return False

              @3: You can prevent the class from being registered by c4dtools.plugins.main() and
              register it yourself. This information is contained in the source-code inline documentation,
              see https://github.com/NiklasRosenstein/c4dtools/blob/master/c4dtools/plugins.py#L12.

              class MyCommand(c4dtools.plugins.Command) :
                    # ...
                    autoregister = False

              instance = MyCommand()
                instance.register()

              Symbols

              @1: This is the way to access the symbols. You can of course call the variable whatever you
              like, con as well of course.

              con, importer = c4dtools.prepare(__file__)
                  print con.IDC_MYSYMBOL

              @2: The res.string slot points to a c4dtools.resource.StringLoader instance. Requesting an
              attribute will return a callable object wrapping c4d.plugins.GeLoadString with the symbol-id
              already set. Therefore, the returned callable object accepts 4 parameters (like the GeLoadString
              function does, minus 1 because the id is already set).
              See https://github.com/NiklasRosenstein/c4dtools/blob/master/c4dtools/resource.py#L163

              @3: Don't get it. Do you mean calling a function for each symbol and instead of taking the symbols
              id, taking the functions return value as value for the symbol?

              -Nik

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 07/01/2013 at 15:40, xxxxxxxx wrote:

                Originally posted by xxxxxxxx

                @3: Don't get it. Do you mean calling a function for each symbol and instead of taking the symbols
                id, taking the functions return value as value for the symbol?

                It would be a new functionality completely unrelated to the dialog ressource loading features.

                res file :

                CONTAINER mynode
                {
                	[...]
                	DATETIME STAGE_BUDGET { ANIM OFF; TIME_CONTROL; OPEN;}
                	[...]
                }
                

                now:

                class mynode(plugins.ObjectData) :
                    def Init(self, node) :
                	[...]
                        self.InitAttr(node, c4d.DateTimeData, c4d.STAGE_BUDGET)
                	[...]
                

                what would be cool :

                class mynode(plugins.ObjectData) :
                    def Init(self, node) :
                	# does the same as the example above
                	res.InitAttributes(self, node, relatedRessourcFile)
                
                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 08/01/2013 at 03:56, xxxxxxxx wrote:

                  Hello Ferdinand,

                  I did not know you were not referring to dialogs, but to descriptions. The current implementation
                  does not parse the description symbols as they are automatically loaded in to the c4d module.
                  Although it would not be a problem parsing the descriptions' symbol-files (*.h), it would be very
                  much work parsing the *.res files, which is required to get the information how to initialize the
                  attributes in the node.

                  PS: I know about the symbolcache issue.. Still not a reason for me to include the description
                  symbols in the res parser.

                  -Nik

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 08/01/2013 at 08:25, xxxxxxxx wrote:

                    I admit that parsing the description symbols as well might be useful sometimes, but I don't
                    want it to be the default behavior. One can now optionally parse the description symbols. The
                    code has been committed to the development branch. See
                    https://github.com/NiklasRosenstein/c4dtools/commit/7e09b5f8f321af76717af2596d1bd4de0206a2fb.
                    The argument parse_descriptions must be set to True on c4dtools.prepare() for this.

                    Thanks for your feedback Ferdinand 😉

                    -Niklas

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 14/01/2013 at 06:56, xxxxxxxx wrote:

                      Hey Niklas, fantastic stuff as always. I don't have the time to look into it right now, but if it does what you say it should be a very handy timesaver in the future.
                      Thank you for sharing!

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 30/01/2013 at 04:08, xxxxxxxx wrote:

                        I like the initiative!
                        Do you have an overview / documentation of all functions in this library?

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          On 01/02/2013 at 09:48, xxxxxxxx wrote:

                          Hi pgroof,

                          I've added a Sphinx documentation to the repository. You can find it under docs/build/html.

                          I have also merged the development branch into the master branch, c4dtools is now on Version 1.0.1.

                          Best,
                          Niklas

                          1 Reply Last reply Reply Quote 0
                          • H
                            Helper
                            last edited by

                            On 14/02/2013 at 06:48, xxxxxxxx wrote:

                            UPDATE: 1.1.0

                            The c4dtools library has been improved and is now licensed under the Simplified BSD License,
                            allowing it to be  used in commercial projects! The documentation has been updated as well and
                            is included in the repository.

                            Grab it from github!

                            -Niklas

                            1 Reply Last reply Reply Quote 0
                            • H
                              Helper
                              last edited by

                              On 22/03/2013 at 11:12, xxxxxxxx wrote:

                              Hi!

                              The c4dtools library has been updated to 1.2.8. The new version includes some extremely cool new
                              features. The documentation has also been updated.

                              Some of the new features include:

                              • Menu resource parser: Don't fuzz with GeDialog.MenuAddString(), ~MenuAddSeparator() etc. anymore! Easily create menu resource files, automatically enabling multilanguage support! (requires scan module) [c4dtools.resource.menuparser]
                              • Dialog parameter manager: Store and restore values of parameters in dialogs! Retrieve and set dialog parameters in a comfortable and elegant way. (c4dtools.misc.dialog)
                              • c4dtools.utils.AtomDict: Dictionary-like object. Enables to use c4d.C4DAtom objects to be used as dictionary keys!
                              • Updated the c4dtools.utils.Importer class to behave correctly regarding to importing external dependencies. (see this post).
                              • Polygon-normal alignment: Utility functions for finding normals facing into the wrong direction! (c4dtools.misc.normalalign)

                              c4dtools.misc.dialog

                              Here's a small code-snippet that demonstrates using the c4dtools.misc.dialog module:

                              class MainDialog(c4d.gui.GeDialog) :
                                
                                  # Must be a unique plugincafe identifier!
                                  ID_DATA = 1001204
                                
                                  def __init__(self) :
                                      super(MainDialog, self).__init__()
                                      self.params = c4dtools.misc.dialog.DefaultParameterManager()
                                
                                      # Initialize the Parameter Manager.
                                      p = self.params
                                
                                      p.add('reset_axes', res.CHK_RESETAXES, 'b', True)
                                      p.add('optimize', res.CHK_OPTIMIZE, 'b', True)
                                      p.add('optimize_tolerance', res.EDT_OPTIMIZE_TOLERANCE, 'm', 0.01)
                                      p.add('set_phong_angle', res.CHK_SETPHONGANGLES, 'b', True)
                                      p.add('phong_angle', res.EDT_PHONGANGLE, 'd', math.radians(21))
                                      p.add('untri', res.CMB_UNTRIANGULATE, 'i', res.CMB_UNTRIANGULATE_NGONS)
                                
                                  def InitValues(self) :
                                      # Load saved values.
                                      bc = c4d.plugins.GetWorldPluginData(self.ID_DATA)
                                      self.params.load_container(self, bc)
                                      return True
                                
                                  def AskClose(self) :
                                      # Store the dialog values.
                                      params = getattr(self, 'params', None)
                                      if params:
                                          bc = params.to_container(self)
                                          c4d.plugins.SetWorldPluginData(self.ID_DATA, bc, False)
                                
                                      # Close the dialog.
                                      return False
                              

                              c4dtools.resource.menuparser

                              Since this module requires the scan module, it is not imported implcitly and the c4dtools library can safely be used without this dependency installed!

                              Here's a small code-snippet on how to use MENU resources:

                              res, imp = c4dtools.prepare(__file__, __res__)
                                
                              class MyDialog(c4d.gui.GeDialog) :
                                
                                  MENU_FILE = res.file('menu', 'my_menu.menu')
                                  RECENTS_START = 1000000
                                
                                  def CreateLayout(self) :
                                      menu = c4dtools.resource.menuparser.parse_file(self.MENU_FILE)
                                      recents = menu.find_node(res.MENU_FILE_RECENTS)
                                
                                      item_id = self.RECENTS_START
                                      for fn in get_recent_files() : # arbitrary function
                                          node = c4dtools.resource.menuparser.MenuItem(item_id, str(fn))
                                          recents.add(node)
                                
                                      # Render the menu on the dialog, passing the dialog itself
                                      # and the c4dtools resource.
                                      self.MenuFlushAll()
                                      menu.render(self, res)
                                      self.MenuFinished()
                                
                                      # ...
                                      return True
                              

                              The corresponding MENU resource looks like this:

                              # Write comments like in Python.
                              MENU MENU_FILE {
                                  MENU_FILE_OPEN;
                                  MENU_FILE_SAVE;
                                  --------------;         # Adds a separator.
                                  COMMAND COMMAND_ID;     # Uses GeDialog.MenuAddCommand().
                                  COMMAND 5159;           # Same here.
                                
                                  # Create a sub-menu.
                                  MENU_FILE_RECENTS {
                                      # Will be filled programatically.
                                  }
                              }
                              # More menus may follow ...
                              

                              The symbols used in the menu resource must be defined in the res variable passed to the render() method.

                              Online Documentation

                              The c4dtools library now has an index in the Python Package Index and the 1.2.8 documentation is hosted online at http://pythonhosted.org/c4dtools/.

                              Edit: corrected example code

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post