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

    Adding items to a LONG/CYCLE description container.

    Cinema 4D SDK
    python r20
    3
    4
    1.6k
    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.
    • FlavioDinizF
      FlavioDiniz
      last edited by

      Hi !

      I'm finishing developing my first python tag plugin but there's one thing that I can't figure out how to do.... I've read the documentation and searched for some examples, but no success 😞

      Basically I want to add a list of string to the File LONG CYCLE container.
      0_1540075049978_ask.png

      This is the part on my .py file where I get the strings:

      datafilename = tag.GetDataInstance()
      path = datafilename.GetFilename(STRINGTEST)
      
      extensions = ["exr","hdr","jpg","png"]
      c = 0
      files = os.listdir(path)
      for names in files:
          ext = names.rsplit(".",1)
          if ext[1] in extensions:
              c = c + 1
              lista = c
              lista = str(c)+';'+path+'\\'+names
              print lista
      

      This is the part of my .res file where the cointainer is:

      FILENAME STRINGTEST {DIRECTORY;}
      LONG TESTSCALE 
      {
          CYCLE
          {
      
          }
      }
      

      I think I would be able to do this with GetDDescription, but I have no idea and haven't found examples in how to do it 😞

      Does anyone know how to do it ? 😄

      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Hi @FlavioDiniz, first of all, welcome in the plugincafe community!

        Don't worry, since it's your first topic, I've set up your topic correctly. But please for your next topics, use the Q&A functionnaly, make sure to also read How to Post Questions.

        With that's said you can find the manual about SetDParameter in the C++ docs which will be trigger each time a user changes a value in the description of your tag. And also the C++ manual about GetDDescription.
        Here a quick example of the implementation in python

            extensions = ["exr","hdr","jpg","png"]
        
            # Called by C4D when loading description
            def GetDDescription(self, node, description, flags):
                data = node.GetDataInstance()
                if data is None:
                    return False
        
                # Load the description
                if not description.LoadDescription(node.GetType()):
                    return False
        
                # If there is no description for c4d.TESTSCALE, we create it. Otherwise we override it and set DESC_CYCLE with our extensions list.
                singleID = description.GetSingleDescID()
                paramID = c4d.DescID(c4d.TESTSCALE)
                if singleID is None or paramID.IsPartOf(singleID)[0]:
                    bcParam = description.GetParameterI(c4d.TESTSCALE)
        
                    items = c4d.BaseContainer()
                    for i, extension in enumerate(self.extensions):
                        items.SetString(i, extension)
        
                    bcParam[c4d.DESC_CYCLE] = items
        
                return (True, flags | c4d.DESCFLAGS_DESC_LOADED)
        
            # Called when a parameter is Set
            def SetDParameter(self, node, id, t_data, flags):
                if not node:
                    return
        
                # called when the filename is changed. We add the path to our list and we return c4d.DESCFLAGS_PARAM_SET to inform c4d the paramaters is just sets
                if id[0].id == c4d.STRINGTEST:
                    self.extensions.append(t_data)
                    return (True, flags | c4d.DESCFLAGS_PARAM_SET)
        
                return False
        

        If you have any questions, please let me know!
        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        FlavioDinizF 1 Reply Last reply Reply Quote 3
        • FlavioDinizF
          FlavioDiniz @m_adam
          last edited by

          hi @m_adam, thanks a lot for your answer!

          I spent two days trying to implement the function in my code, but no success again 😞
          I think the problem now is more related to python than the C4D SDK,i'm not that experienced on it...

          The error i'm getting is:
          AttributeError: 'testplugin' object has no attribute 'hdrs'
          alt text

          hdrs is the list of strings (file paths), but seems that this list cannot be read by the GetDDescription function....
          I've tried putting it as a global variable, also putting under testplugin class, under Execute, etc..
          Tried putting the GetDDescription and SetDParameter as a inner function of Execute (I think this is wrong.. didn't give me errors, but updating the cycle doesn't work too haha).

          Here's the structure of my plugin, I removed some irrelevant parts so we can focus better where the error is...
          Do you think the structure is correct or am I missing something ?

          the .res file is the same as in my first post.

          import c4d
          import os
          import sys
          from c4d import gui, plugins, bitmaps
          
          PLUGIN_ID = 1000001
          TESTSCALE = 1001
          STRINGTEST = 1003
          
          class testplugin(plugins.TagData):
              
              def Init(self, node):
                  tag = node
                  data = tag.GetDataInstance()
                  FDWhite = c4d.Vector(1,1,1)
                  data.SetBool(FDENABLEBG, True)
                  data.SetInt32(FDSATURATION, 100)
                  data.SetVector(FDTINT, FDWhite)
                  data.SetInt32(FDSAMPLES, 64)
          
              def Execute(self, tag, doc, op, bt, priority, flags):
                  datafilename = tag.GetDataInstance() #FD Folder path
                  path = datafilename.GetFilename(STRINGTEST)
          
                  extensions = ["exr","hdr"]
                  hdrs = []
                  if path != "":
                      files = os.listdir(path)
                      for names in files:
                          ext = names.rsplit(".",1)
                          if ext[1] in extensions:
                              hdrs.append(path+'\\'+names)
          
                  return c4d.EXECUTIONRESULT_OK
          
              def GetDDescription(self, node, description, flags): # Called by C4D when loading description
                  data2 = node.GetDataInstance()
                  if data2 is None:
                      return False
          
                  if not description.LoadDescription(node.GetType()): # Load the description
                      return False
          
                  singleID = description.GetSingleDescID()
                  paramID = c4d.DescID(c4d.TESTSCALE)
                  if singleID is None or paramID.IsPartOf(singleID)[0]:
                      bcParam = description.GetParameterI(c4d.TESTSCALE)
          
                      items = c4d.BaseContainer()
                      for i, hdrs in enumerate(self.hdrs):
                          items.SetString(i, hdrs)
          
                      bcParam[c4d.DESC_CYCLE] = items
                  return (True, flags | c4d.DESCFLAGS_DESC_LOADED)
          
              
              def SetDParameter(self, node, id, t_data, flags): # Called when a parameter is Set
                  if not node:
                      return
          
                  if id[0].id == c4d.STRINGTEST:
                      self.hdrs.append(t_data)
                      return (True, flags | c4d.DESCFLAGS_PARAM_SET)
                  return False
          
          if __name__ == "__main__":
              bmp = bitmaps.BaseBitmap()
              dir, file = os.path.split(__file__)
              bitmapfile = os.path.join(dir, "res", "icon.tif")
              result = bmp.InitWith(bitmapfile)
              plugins.RegisterTagPlugin(id=PLUGIN_ID, str="FD HDR", info=c4d.TAG_EXPRESSION|c4d.TAG_VISIBLE, g=testplugin, description="testplugin", icon=bmp)
              
          

          thanks again 🙂

          1 Reply Last reply Reply Quote 0
          • M
            mp5gosu
            last edited by

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

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