InExclude in a CommandData plugin [SOLVED]



  • On 22/02/2017 at 12:29, xxxxxxxx wrote:

    Hey everyone. I am writing a command data plugin, well, updating an old one i made forever ago, and I am trying to add in some stuff with inexclude boxes so I can have groups of objects. The ultimate goal is to simple iterate over the objects that are placed in the inexclude box and do stuff to them, in my case, adding tags to them. I've been screwing with this for several hours with no luck.

    I have created a simple stripped down plugin to help get this working, it is just an inexclude box and a button to print stuff to the console. It helps illustrate what I am trying to do.  The code is below, as well as a link to the plugin files to mess with.

    plugin: https://dl.dropboxusercontent.com/u/13668972/stupid/inexclude_tests.zip

      
    import c4d
    from c4d import documents, gui, plugins, bitmaps
    import os
      
      
    c4dversion = str(c4d.GetC4DVersion())[:2]
    c4dversion = int(c4dversion)
      
    PLUGIN_ID = 100000254
    PLUGIN_NAME = "INEXCLUDE TESTS"
    PLUGIN_DESC = "blah"
    VERSION = "1"
      
      
    BTN_CONFIRM = 1013
      
    """
    I used this thread for creating the in/exclude box.
    https://plugincafe.maxon.net/topic/9626/12928_inexclude-list-python-plugin&KW=CUSTOMGUI_INEXCLUDE_LIST
      
    the ultimate goal, is to be able to iterate over the objects placed in the box
      
    i have my main plugin setup and ready, but getting objects from the inexclude box is giving me issues
      
    I found this video from Pim Grooff but it does not seem to be helping me with a CommandData plugin
    https://www.youtube.com/watch?v=DIksYqMLn3s
      
    in it, he is using a tag plugin, using a node instance with data = tag.GetDataInstance() then later
    using inex = data[MY_LISTBOX] where MY_LISTBOX is the description from the res file of the inexclude gui element
      
    he can then use inex.GetObjectCount()
    I cannot figure out how to get that far. Nothing I do seems to work. I simply want to be able to grab the
    objects in the box.
    """
      
    class INEXMODAL(gui.GeDialog) :
      
        def InitValues(self) :
            return True
      
        def CreateLayout(self) :
            __title__ = "{0} v{1}".format(PLUGIN_NAME, VERSION)
            self.SetTitle(__title__)
      
            self.GroupBegin(0, c4d.BFH_CENTER | c4d.BFV_CENTER, cols=1)
            self.GroupBorderNoTitle(c4d.BORDER_NONE)
      
            # First create a container that will hold the items we will allow to be dropped into the INEXCLUDE_LIST gizmo
            acceptedObjs = c4d.BaseContainer()
            acceptedObjs.InsData(c4d.Obase, "")
      
            # Create another container for the INEXCLUDE_LIST gizmo's settings and add the above container to it
            IEsettings = c4d.BaseContainer()
            IEsettings.SetData(c4d.DESC_ACCEPT, acceptedObjs )
      
            # Lastly, create the  INEXCLUDE_LIST gizmo itself and point it at the "IEsettings" container
            self.inexbox = self.AddCustomGui(5001, c4d.CUSTOMGUI_INEXCLUDE_LIST, "", c4d.BFH_SCALEFIT | c4d.BFV_CENTER, 600, 300, IEsettings)
      
            # add a button to print out info
            self.AddButton(BTN_CONFIRM, c4d.BFH_CENTER | c4d.BFV_CENTER, 0, 20, 'print inex stuff')
      
            return True
      
        def Command(self, id, msg) :
      
            if id == BTN_CONFIRM:
                # this gives me an error, AttributeError: 'module' object has no attribute 'GetParameter'
                # box = c4d.GetParameter(5001, c4d.DESCFLAGS_GET_0)
      
                # this prints: <c4d.gui.InExcludeCustomGui object at 0x0000022DB48F7DC8>
                box = self.inexbox
      
                if c4dversion >= 16 :
                    # C4DAtom.GetParameter(id, flags) was added in 16.021 but that returns and error for me
                    pass
      
                if c4dversion >= 18:
                    # apparently in r18 you can use Description.GetParameter(id, ar) but im not getting that to work either
                    pass
      
                print(box)
      
            return True
      
      
    class INEX(plugins.CommandData) :
        dialog = None
      
        def Execute(self, doc) :
            if self.dialog is None:
                self.dialog = INEXMODAL()
            return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, xpos=-1, ypos=-1, defaultw=300, defaulth=0)
      
        def RestoreLayout(self, sec_ref) :
            if self.dialog is None:
                self.dialog = INEXMODAL()
            return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
      
      
    if __name__ == '__main__':
        bmp = c4d.bitmaps.BaseBitmap()
        dir, file = os.path.split(__file__)
        fn = os.path.join(dir, "res", "icons", "inex.tif")
        bmp.InitWith(fn)
        result = plugins.RegisterCommandPlugin(PLUGIN_ID, PLUGIN_NAME, 0, bmp, PLUGIN_DESC, INEX())
    

    Thanks for any help,
    Charles



  • On 23/02/2017 at 02:08, xxxxxxxx wrote:

    Hi Charles,

    An InExcludeCustomGui could be added to a dialog layout in pre R18 versions but its data couldn't be changed and retrieved.
    R18 brought the new methods BaseCustomGui.GetData()/BaseCustomGui.SetData() that enable to obtain and set a custom GUI data (InExcludeData in the case of the InExcludeCustomGui). Note all custom GUIs inherit BaseCustomGui.

    # this gives me an error, AttributeError: 'module' object has no attribute 'GetParameter'
    # box = c4d.GetParameter(5001, c4d.DESCFLAGS_GET_0)
    

    This gives an error because GetParameter() is called on the c4d module. This function has to be called on a node or object in the document.

    if c4dversion >= 16 :
        # C4DAtom.GetParameter(id, flags) was added in 16.021 but that returns and error for me
        pass
      
    if c4dversion >= 18:
        # apparently in r18 you can use Description.GetParameter(id, ar) but im not getting that to 
    

    The InExcludeCustomGui in a dialog doesn't store its data in a parameter like an InExclude parameter of an object. Descriptions and dialogs are different:
    Node plugins (ObjectData, TagData etc.) use a description resource to declare parameters and to provide a UI for the Attribute Manager.
    Dialogs use a dialog resource or a manual layout in GeDialog.CreateLayout().

    To retrieve the InExcludeCustomGui data call BaseCustomGui.GetData() (only available in R18) :

    box = self.inexbox
    if box is not None:
        data = box.GetData()
        print data
    


  • On 23/02/2017 at 06:38, xxxxxxxx wrote:

    Yannick,

    Thanks for the help. I tried out your code in r18 and it works just like I would expect. It really sucks you can't access the data in earlier versions but oh well. I will just enable this feature for r18 and up and think of something else for earlier versions of cinema. Maybe I will skip it for earlier versions all together for now; not sure yet.

    Thanks again dude


Log in to reply