Navigation

    • Register
    • Login
        No matches found
    • Search
    1. Home
    2. danielsian
    3. Posts
    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups

    Posts made by danielsian

    RE: Test "Lock Overrides" in Python

    Thank you very much @ferdinand, that's exactly what I was looking for.
    Cheers

    posted in Cinema 4D SDK •
    Test "Lock Overrides" in Python

    Hi there, is it possible to test "Lock Overrides" and return if it is on or off using Python?
    The same question for the "Enable all overrides" button.

    Cheers

    posted in Cinema 4D SDK •
    RE: Copying Take Overrides from an object to another via Python not working properly

    @m_magalhaes said in Copying Take Overrides from an object to another via Python not working properly:

    adding the backupvalue

    You are master!
    thanks my friend, it's working!

    posted in Cinema 4D SDK •
    Copying Take Overrides from an object to another via Python not working properly

    Hi there, I'm working on a script to transfer (or copy) the overrides from a source object to a target one and it seems to be working if there is no overrides in sub-Takes.
    Basically what the script does is a scan through all Takes starting from the first after the Main (takeData.GetMainTake().GetDown()) and retrieves each override ID and value and it adds to the target object via FindOrAddOverrideParam().
    But for any odd reason the result is not consistent if there are sub-Takes involved as it changes depending on which one is active before running the script, and in all cases, I would expect a perfect copy but that's not what's happening. I must be missing something here 😕
    My gut feeling says that the problem is related to the backup so I just tried forcing it via FindOverrideCounterPart() but without success.

    02a090bd-ef4a-420d-8114-2457f031e39d-image.png
    6cca585d-2e1a-442f-acff-3d0a46ba829a-image.png
    ed31f56c-a080-4f74-b66d-d4aabfbc950d-image.png
    3e4da7b3-cd3d-483f-99dd-d1f4b7913664-image.png
    844555aa-6146-47ba-89f2-abd4b37c326c-image.png
    9c284837-6deb-43ad-8d7b-3ac280597831-image.png
    740b2c65-d301-47e2-91c1-e87a97735910-image.png

    I'm sending a dummy file attached with a set of Takes just to show the problem I'm trying to describe here:

    copy_overrides_to_another_object.c4d

    This is the script that works with the file above:

    import c4d
    
    def GetNextTake(op):
        if op == None: return None
        if op.GetDown(): return op.GetDown()
        while not op.GetNext() and op.GetUp(): op = op.GetUp()
        return op.GetNext()
    
    def getDescIdName(op, descID):
        description = op.GetDescription(c4d.DESCFLAGS_DESC_0)
        for bc, paramid, groupid in description:
            if paramid == descID:
                return bc[c4d.DESC_NAME]
    
    def TransferTakeOverrides(srcObj, trgObj, takeData, currentTake):
        while currentTake:
            srcOverride = currentTake.FindOverride(takeData, srcObj)
            if srcOverride is not None:
                for descID in srcOverride.GetAllOverrideDescID():
    
                    # Get the backup node for the source override
                    backup, result = takeData.FindOverrideCounterPart(srcOverride, descID) # backup: The counterpart node // result: the Take
    
                    if backup is None:
                        raise RuntimeError("Failed to find the default override.")
    
                    # Get the backup value of the given Description ID
                    backupValue = backup.GetParameter(descID, c4d.DESCFLAGS_GET_0)
    
                    print(currentTake.GetName(), "      DescID:", getDescIdName(srcObj,descID))
                    print(" --->",srcOverride.GetSceneNode().GetName())
                    print("        overr. value:", srcOverride.GetParameter(descID, c4d.DESCFLAGS_GET_0))
                    print("        backup value:", backupValue,"from", result.GetName())
    
                    # Get the override value
                    srcOverValue = srcOverride.GetParameter(descID, c4d.DESCFLAGS_GET_0)
                    # add override to the target object
                    trgOverride = currentTake.FindOrAddOverrideParam(takeData, trgObj, descID, srcOverValue)
    
                    # Get the backup node for the target override
                    trg_backup, trg_result = takeData.FindOverrideCounterPart(trgOverride, descID)
                    trg_backupValue = trg_backup.GetParameter(descID, c4d.DESCFLAGS_GET_0)
    
                    # force adding source backup value to the target backup take (just trying to fix the problem!)
                    trgBackup = trg_result.FindOrAddOverrideParam(takeData, trgObj, descID, backupValue)
                    trgBackup.UpdateSceneNode(takeData, descID)
    
                    trgOverride.UpdateSceneNode(takeData, descID)
    
                    print(" --->",trgOverride.GetSceneNode().GetName())
                    print("        overr. value:", trgOverride.GetParameter(descID, c4d.DESCFLAGS_GET_0))
                    print("        backup value:", trg_backupValue,"from", trg_result.GetName())
                    print("        ----------------")
    
                currentTake = GetNextTake(currentTake)
                print("======================================")
    
    def main():
        op = c4d.BaseObject(c4d.Ocube)
        op[c4d.ID_BASELIST_NAME] = "trg_Cube"
        doc.InsertObject(op)
        objs = doc.GetObjects()
        objs.reverse()
    
        if len(objs) != 2: return
    
        takeData = doc.GetTakeData()
        currentTake = takeData.GetMainTake().GetDown()
    
        TransferTakeOverrides(srcObj=objs[0], trgObj=objs[1], takeData=takeData, currentTake=currentTake)
    
        c4d.EventAdd()
    
    if __name__=='__main__':
        main()
    
    posted in Cinema 4D SDK •
    RE: How to pass a value from GeDialog to another class

    @ferdinand Thank you for your awesome explanation!
    I will keep this post as a reference for my studies as your approach seems a bit complicated for my understanding at the moment.
    I'm learning a lot with your contribution in this forum, and in this case here it's not gonna be different.
    Cheers

    posted in Cinema 4D SDK •
    RE: How to pass a value from GeDialog to another class

    @cairyn thanks for your time and helpful answer.
    I was trying to retrieve the value of a variable from another class by calling it directly. This is why you could see OptionsDialog() within class processing. This is the source of my problems, because as far as I know, this is how a class variable should be called from another class.
    Probably I'm wrong or things are different when there's a dialog involved 😕

    Anyways, this is the working code, with your solution addressed:

    import c4d
    
    pluginVersion = "v1.0.0"
    pluginName = "Get Value From Dialog"
    PLUGIN_ID = 1111222
    
    class OptionsDialog (c4d.gui.GeDialog):
        GROUP_OPTIONS = 1011
        CHKBX1 = 1007
        CHKBX2 = 1008
        CHKBX3 = 1009
        BTN_OK = 1010
        def __init__(self):
            self._hasBeenInitalized = False
            self._hasLayoutDone = False
    
        def Message(self, msg, result):
            if msg.GetId() == c4d.BFM_ACTION: msg[c4d.BFM_ACTION_VALUE]        
            return c4d.gui.GeDialog.Message(self, msg, result)
        
        def CreateLayout(self):
            self.SetTitle(pluginName + ' ' + pluginVersion)
            self.AddCheckbox(self.CHKBX1, c4d.BFH_SCALEFIT, initw=1, inith=1, name='Checkbox 1')
            self.AddCheckbox(self.CHKBX2, c4d.BFH_SCALEFIT, initw=1, inith=1, name='Checkbox 2')
            self.AddCheckbox(self.CHKBX3, c4d.BFH_SCALEFIT, initw=1, inith=1, name='Checkbox 3')
            if self.GroupBegin(self.GROUP_OPTIONS, c4d.BFH_CENTER, 1, 1):
                self.AddButton(self.BTN_OK, c4d.BFH_SCALEFIT,  initw=500, inith=15,name='Go!')
            self.GroupEnd()
            self._hasLayoutDone = True
            self._hasBeenInitalized = False
            return True
    
        def Command(self, id, msg):
            if id==self.BTN_OK or id==c4d.IDC_OK:
                self.print_msg1 = self.GetBool(self.CHKBX1)
                self.print_msg2 = self.GetBool(self.CHKBX2)
                self.print_msg3 = self.GetBool(self.CHKBX3)
                self.Run()
            return True
    
        def InitValues(self):
            if self._hasBeenInitalized is True:
                return True
            self.SetBool(self.CHKBX1, True)
            self._hasBeenInitalized = True
            return True
    
        def Run(self):
            message = processing().set_nice_message(self.print_msg1, self.print_msg2, self.print_msg3)
            print(message)
            c4d.EventAdd()
            return True
    
    class processing:
        def set_nice_message(self, msg1, msg2, msg3):
            if msg1: result = 'Hello world 1'
            if msg2: result = 'Hello world 2'
            if msg3: result = 'Hello world 3'
            return result
    
    class DialogCommandData(c4d.plugins.CommandData):
        dlg = None
    
        def Execute(self, doc):
            if self.dlg is None:
                self.dlg = OptionsDialog()
            return self.dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC,
                                     pluginid=PLUGIN_ID,
                                     xpos=-2, ypos=-2, defaultw=720, defaulth=50)
    
        def RestoreLayout(self, secret):
            if self.dlg is None:
                self.dlg = OptionsDialog()
            return self.dlg.Restore(pluginid=PLUGIN_ID, secret=secret)
    
    if __name__ == '__main__':
        myPlugin = DialogCommandData()
        c4d.plugins.RegisterCommandPlugin(id=PLUGIN_ID,
                                    str=pluginName,
                                    info=0,
                                    icon=None,
                                    help=pluginName,
                                    dat=myPlugin)
    
    posted in Cinema 4D SDK •
    How to pass a value from GeDialog to another class

    This is probably a silly question, but I'm stuck and need some help so I can move forward in my plugin without using global dialog.
    The original dialog has much more checkboxes and edit texts to guide the whole processing, but I've been able to get a very simplified sample of my code with a similar structure.

    I have a class

    class processing
    

    that needs to retrieve data from the dialog in order to process the script, but I really don't know how to get it since the code below is returning this error:

    AttributeError: 'OptionsDialog' object has no attribute 'print_msg1'
    

    I have to keep the structure like it is at the moment.

    This the sample, any help would be awesome:

    import c4d
    
    pluginVersion = "v1.0.0"
    pluginName = "Get Value From Dialog"
    PLUGIN_ID = 1111222
    
    class OptionsDialog (c4d.gui.GeDialog):
        GROUP_OPTIONS = 1011
        CHKBX1 = 1007
        CHKBX2 = 1008
        CHKBX3 = 1009
        BTN_OK = 1010
        def __init__(self):
            self._hasBeenInitalized = False
            self._hasLayoutDone = False
    
        def Message(self, msg, result):
            if msg.GetId() == c4d.BFM_ACTION: msg[c4d.BFM_ACTION_VALUE]        
            return c4d.gui.GeDialog.Message(self, msg, result)
        
        def CreateLayout(self):
            self.SetTitle(pluginName + ' ' + pluginVersion)
            self.AddCheckbox(self.CHKBX1, c4d.BFH_SCALEFIT, initw=1, inith=1, name='Checkbox 1')
            self.AddCheckbox(self.CHKBX2, c4d.BFH_SCALEFIT, initw=1, inith=1, name='Checkbox 2')
            self.AddCheckbox(self.CHKBX3, c4d.BFH_SCALEFIT, initw=1, inith=1, name='Checkbox 3')
            if self.GroupBegin(self.GROUP_OPTIONS, c4d.BFH_CENTER, 1, 1):
                self.AddButton(self.BTN_OK, c4d.BFH_SCALEFIT,  initw=500, inith=15,name='Go!')
            self.GroupEnd()
            self._hasLayoutDone = True
            self._hasBeenInitalized = False
            return True
    
        def Command(self, id, msg):
            if id==self.BTN_OK or id==c4d.IDC_OK:
                self.print_msg1 = self.GetBool(self.CHKBX1)
                self.print_msg2 = self.GetBool(self.CHKBX2)
                self.print_msg3 = self.GetBool(self.CHKBX3)
                self.Run()
            return True
    
        def InitValues(self):
            if self._hasBeenInitalized is True:
                return True
            self.SetBool(self.CHKBX1, True)
            self._hasBeenInitalized = True
            return True
    
        def Run(self):
            message = processing().set_nice_message()
            print(message)
            c4d.EventAdd()
            return True
    
    class processing:
        dlg = OptionsDialog()
        def set_nice_message(self):
    
            """ how can I get values from OptionsDialog() ???
            """
            if self.dlg.print_msg1: result = 'Hello world 1'
            if self.dlg.print_msg2: result = 'Hello world 2'
            if self.dlg.print_msg3: result = 'Hello world 3'
            return result
    
    class DialogCommandData(c4d.plugins.CommandData):
        dlg = None
    
        def Execute(self, doc):
            if self.dlg is None:
                self.dlg = OptionsDialog()
            return self.dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC,
                                     pluginid=PLUGIN_ID,
                                     xpos=-2, ypos=-2, defaultw=720, defaulth=50)
    
        def RestoreLayout(self, secret):
            if self.dlg is None:
                self.dlg = OptionsDialog()
            return self.dlg.Restore(pluginid=PLUGIN_ID, secret=secret)
    
    
    if __name__ == '__main__':
        myPlugin = DialogCommandData()
        c4d.plugins.RegisterCommandPlugin(id=PLUGIN_ID,
                                    str=pluginName,
                                    info=0,
                                    icon=None,
                                    help=pluginName,
                                    dat=myPlugin)
    
    posted in Cinema 4D SDK •
    RE: Drag and Drop external image in a gui Edit Text box with Python

    Great!
    Cheers!

    posted in Cinema 4D SDK •
    RE: Drag and Drop external image in a gui Edit Text box with Python

    Hey Ferdinand, thank you very much for your time. I really appreciate that!

    A custom GUI is so much easier, that I think my whole script is gonna be much shorter and with a pretty nice new functionality.

    Cheers

    posted in Cinema 4D SDK •
    Drag and Drop external image in a gui Edit Text box with Python

    I have a gui.GeDialog with a few Edit Text boxes and I wanted to drop textures from my Windows Explorer on there and get the full path of each texture, just like in the texture field on a material.

    I found a couple of useful posts approaching the same question, but the solution seems to be directed to more experienced Python users, as they have only parts of code, not a full working example.

    I'd appreciate if someone could share an example on how to do that in this dialog here:

    import c4d
    
    class MyDialog(c4d.gui.GeDialog):
    
        def CreateLayout(self):
            
            self.AddEditText(1000, c4d.BFH_SCALEFIT, initw=0, inith=0)
            self.AddEditText(1001, c4d.BFH_SCALEFIT, initw=0, inith=0)
            self.AddEditText(1002, c4d.BFH_SCALEFIT, initw=0, inith=0)
            self.AddEditText(1003, c4d.BFH_SCALEFIT, initw=0, inith=0)
            return True
    
    def main():
        dialog = MyDialog()
        dialog.Open(dlgtype=c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=500, defaulth=500)
    
    if __name__ == '__main__':
        main()
    
    posted in Cinema 4D SDK •
    RE: Drag&Drop an image in a gui field

    @pim I'm trying to figure out how you did this. Could you please share a sample code of this example?
    I'm trying to get the full path of an image by dragging it into a edit text field...

    Cheers

    posted in Cinema 4D SDK •
    RE: Gui Dialog in Python not respecting the dimensions

    Hi Manuel

    I've used the "Upload Image" button, don't know why the image is not visible for you.

    I'm using Windows 10.

    I hope you are able to see this one:

    alt text

    Cheers

    posted in Cinema 4D SDK •
    RE: Gui Dialog in Python not respecting the dimensions

    @m_magalhaes said in Gui Dialog in Python not respecting the dimensions:

    you never specified it was working as expected in R19/R20.

    Hi Manuel

    My fault in not being clear enough, I should have been more specific.

    The problem was implicit, where on the image attached we see "Dialog 700x200px" (defaultw=700, defaulth=200), but with different numbers in red.
    By deduction we can read something as not correct. But again, my fault in not being clear enough, sorry about that.

    So, just to confirm, the issue is about the dimension in pixels not matching what was expected from the code.

    I was expecting a dialog with 700x200 pixels, and was getting 686x193 in R19/20 and 333x146 in R21.

    After your workaround, R21 is working better, but still not matching the 700x200 pixels.

    Thank you again for your time!
    Cheers

    posted in Cinema 4D SDK •
    RE: Gui Dialog in Python not respecting the dimensions

    Hi Manuel

    I think I did it correctly and now I have R21 rendering the dialog exactly like R19 and R20 is doing.
    But I'm struggling to understand why the dialog is being created with slightly smaller dimension than the specified.

    Why is this happening?

    posted in Cinema 4D SDK •
    RE: Gui Dialog in Python not respecting the dimensions

    Hey Manuel, how are you?

    I'm sorry for the mess!
    Could you please provide an example on how this PluginID should be used so we have the function working as expected?

    I am still learning and I appreciate any help.

    Thanks for your time!
    Cheers

    posted in Cinema 4D SDK •
    Gui Dialog in Python not respecting the dimensions

    Hi there

    I'm setting up the dimensions of a dialog in Python, but the result is not correct as you can see on the image below.

    Is this way the right way to do this or there is a better one?

    import c4d
    from c4d import gui
    
    class OptionsDialog(gui.GeDialog):
        def CreateLayout(self):
            self.SetTitle('Dummy Dialog 700x200px')
            self.AddMultiLineEditText(1000, c4d.BFH_SCALEFIT, inith=50, initw=500, style=c4d.DR_MULTILINE_READONLY)
            self.SetString(1000, "Hello World!")
            if self.GroupBegin(1001, c4d.BFH_CENTER, 2, 1):
                self.AddDlgGroup(c4d.DLG_CANCEL|c4d.DLG_OK)
            self.GroupEnd()
            self.ok = False
            return True
        
        def Command(self, id, msg):
            if id==c4d.DLG_CANCEL:
                self.Close()
                return False
            elif id==c4d.DLG_OK:
                self.ok = True
                self.Close()
            return True
    
    def main():
        dlg = OptionsDialog()
        dlg.Open(c4d.DLG_TYPE_MODAL, xpos=-2, ypos=-2, defaultw=700, defaulth=200)
    
    if __name__=='__main__':
        main()
    
    

    dummy_dialog_700x200.jpg

    posted in Cinema 4D SDK •