Navigation

    • Register
    • Login
    • Search
    1. Home
    2. mfersaoui
    3. Posts
    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups

    Posts made by mfersaoui

    Dynamics Body Tag & GetVirtualObjects

    Hello,

    Is it possible that a Dynamics Body Tag added to GVO object can be assigned to all the child virtual objects. like on Fracture Object with Explode Segments mode.

    a code example and screenshot below:

    DynamicsBodyTag-GetVirtualObjects.jpg

    import c4d, os
    from c4d import bitmaps, plugins
    
    class Object(plugins.ObjectData):
        
        def GetVirtualObjects(self, op, hh):
            dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTY_MATRIX | c4d.DIRTY_DATA)
    
            if not dirty:
                return op.GetCache(hh)
    
            cloner = c4d.BaseObject(1018544)
            if cloner is None:
                return c4d.BaseObject(c4d.Onull)
    
            cube = c4d.BaseObject(c4d.Ocube)
            if cube is None:
                return c4d.BaseObject(c4d.Onull)
    
            cube[c4d.PRIM_CUBE_LEN] = c4d.Vector(20.0, 20.0, 20.0)
    
            cube.InsertUnder(cloner)
    
            return cloner
    
    if __name__ == "__main__":
        icon = bitmaps.BaseBitmap()
        icon.InitWith(os.path.join("res", "icons", "icon.tif"))
        plugins.RegisterObjectPlugin(1078197, 'Object', Object, 'Object', c4d.OBJECT_GENERATOR, icon)
    

    Thanks.

    posted in Cinema 4D SDK •
    RE: Placing a custom menu under the File Menu and on specific position

    @mfersaoui
    Hi,
    I found the following solution:

    FileMenu = c4d.BaseContainer()
    resource = c4d.plugins.GeResource()
    resource.InitAsGlobal()
    FileMenu.InsData(c4d.MENURESOURCE_SUBTITLE, resource.LoadString(12587))
    
    posted in Cinema 4D SDK •
    RE: Placing a custom menu under the File Menu and on specific position

    Hi @m_adam,
    I found the solution below that allow to inject my custom menu just after the "IDM_SAVEALL" submenu of "File" menu, but the only problem now is with the following line:
    FileMenu.InsData(c4d.MENURESOURCE_SUBTITLE, "File")

    Because with this solution I must to rebuild all the "IDS_EDITOR_FILE" menu. and I'm searching how to grab the default sub-title of the "IDS_EDITOR_FILE" menu depending on the user interface language. So is there method to get the default subtitle of "IDS_EDITOR_FILE".
    Thanks.

    import c4d, os, sys
    
    def GetMenuContainer(name):
        mainMenu = c4d.gui.GetMenuResource("M_EDITOR")
    
        customMenu = c4d.BaseContainer()
        for bcMenuId, bcMenu in mainMenu:
            if bcMenu[c4d.MENURESOURCE_SUBTITLE] == "IDS_EDITOR_FILE":
                customMenu = mainMenu.GetContainerInstance(bcMenuId)
                break
    
        if customMenu is not None:
            customMenu.FlushAll()
    
    def AddsMenuToC4DMenu(MenuContainer):
        MainMenu = c4d.gui.GetMenuResource("M_EDITOR")
    
        FileMenu = c4d.BaseContainer()
        FileMenu.InsData(c4d.MENURESOURCE_SUBTITLE, "File")
    
        for bcMenuId, bcMenu in MainMenu:
            if bcMenu[c4d.MENURESOURCE_SUBTITLE] == "IDS_EDITOR_FILE":
                for _bcMenuId, _bcMenu in bcMenu:
                    if _bcMenu == "IDM_SAVEALL":
                        cs_menu = c4d.BaseContainer()
                        cs_menu.InsData(c4d.MENURESOURCE_SUBTITLE, "My Menu")
                        cs_menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(menu_id1))
                        cs_menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(menu_id2))
                        cs_menu.InsData(c4d.MENURESOURCE_SEPERATOR, 1) # Append separator
                        cs_menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(menu_id3))
    
                        FileMenu.InsData(1, cs_menu)
                        FileMenu.InsData(c4d.MENURESOURCE_SEPERATOR, 1)
    
                    FileMenu.InsData(_bcMenuId, _bcMenu)
    
        MainMenu.InsDataAfter(c4d.MENURESOURCE_STRING, FileMenu, MenuContainer)
    
    def PluginMessage(id, data):
        if id == c4d.C4DPL_BUILDMENU:
            MenuContainer = c4d.gui.SearchPluginMenuResource("IDS_EDITOR_FILE")
            AddsMenuToC4DMenu(MenuContainer)
            GetMenuContainer("IDS_EDITOR_FILE")
            c4d.gui.UpdateMenus()
    
    posted in Cinema 4D SDK •
    Placing a custom menu under the File Menu and on specific position

    Hello,

    Is it possible to placing a custom menu after specific submenu from the File menu, after the Save submenu for example .

    enhanceMainMenu.png

    The script bellow insert my custom menu at the bottom of the File menu:

    def enhanceMainMenu():
        mainMenu = c4d.gui.GetMenuResource("M_EDITOR")
    
        menu = c4d.BaseContainer()
        menu.InsData(c4d.MENURESOURCE_SUBTITLE, "Custom Menu")
        menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(ID_MENU_1))
        menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(ID_MENU_2))
        #menu.InsData(0, '') # Append separator
        menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_{}".format(ID_MENU_3))
    
        filemenue = mainMenu.GetData(1)
        filemenue.InsData(c4d.MENURESOURCE_SUBMENU, menu)
    
        mainMenu.SetData(1, filemenue)
    
    def PluginMessage(id, data):
        if id == c4d.C4DPL_BUILDMENU:
            enhanceMainMenu()
    

    Thanks.

    posted in Cinema 4D SDK •
    External dependencies question

    Hello,

    I have a plugin that contain multiple subplugins (.pyp files) and want to know how to insert my lib modules to the system path and that affect all the plugin .pyp files. (I have already seen the post: External dependencies: The right way to do and I did not find an answer concerning this point )

    lib\n    module1.py, module2.py, module3.py,...
    res\n    <resource files>
    plugin_1.pyp
    plugin_2.pyp
    plugin_3.pyp
    ...
    

    Must I use the "sys.path.inser()" method on each of my subplugins?
    I noticed that the subplugins is loaded one by one and in alphabetical order. so, for a test I created a new file and I rename it "a.pyp" (to be loaded in the first) and then I put inside it the following code:

    import os
    import sys
      
    dirname = os.path.dirname(__file__)
    lib_path = os.path.join(dirname, 'lib')
    sys.path.insert(0, lib_path)
    

    This it works, and affect all the .pyp files of my plugin.

    Is there a right way to do that?

    Thanks.

    posted in Cinema 4D SDK •
    RE: TreeView Menu

    @mfersaoui said in TreeView Menu:

    GroupBegin

    For my second question I found this function to interact with the htmlViewer area.

    c4d.SpecialEventAdd(ACTION_ID)
    
    posted in Cinema 4D SDK •
    RE: TreeView Menu

    Hi @m_adam ,

    Thank you so much, I have two questions:

    The first is What the right way to rewriting the following code and obtain same result:

    class ListView(c4d.gui.TreeViewFunctions):
    
        def __init__(self):
            self.listOfTexture = list() # Store all objects we need to display in this list
    
    def CreateLayout(self):
    
        self.GroupBegin(0, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 2, 0)
        self.GroupBorderSpace(5, 5, 5, 5)
    
        self.GroupBegin(0, flags=c4d.BFH_LEFT | c4d.BFV_SCALEFIT, cols=1, rows=1, initw=400, inith=0)
    
        # Create the TreeView GUI.
        customgui = c4d.BaseContainer()
        customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN)
        customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, False) # True if the tree view may have a header line.
        customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, False) # True if no lines should be drawn.
        customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, True) # True if the user can move the columns.
        customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True) # True if the column width can be changed by the user.
        customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True) # True if all lines have the same height.
        customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, False) # Alternate background per line.
        customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True) # True if cursor keys should be processed.
        customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, False) # Suppresses the rename popup when the user presses enter.
        customgui.SetBool(c4d.TREEVIEW_NO_MULTISELECT, True)
    
        self._treegui = self.AddCustomGui( 1000, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, customgui)
        if not self._treegui:
            print "[ERROR]: Could not create TreeView"
            return False
    
        self.GroupEnd()
    
        self.GroupBegin(0, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, cols=1, rows=1)
        html_file = "file.html"
        htmlViewer = self.AddCustomGui(1000001, c4d.CUSTOMGUI_HTMLVIEWER, "Viewer", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0)
        htmlViewer.SetUrl(html_file, c4d.URL_ENCODING_UTF16)
        self.GroupEnd()
    
        return True
        
    def InitValues(self):
        # Initialize the column layout for the TreeView.
        layout = c4d.BaseContainer()
        layout.SetLong(ID_NAME, c4d.LV_TREE)
        self._treegui.SetLayout(1, layout)
    
        mdata = {
            "Menu 01": {
                "Item 01": ["sub-item 01", "sub-item 02", "sub-item 03"],
                "Item 02": ["sub-item 01", "sub-item 02"],
                "Item 03": [],
                },
            "Menu 02": [],
            "Menu 03": ["sub-item 01", "sub-item 02"],
            "Menu 04": ["sub-item 01"]
        }
        res = []
        for m in m_data:
            m1 = TextureObject(m)
            res.append(m1)
            m1_items = m_data[m]
            if len(m1_items):
                for m1_name in m1_items:
                    m1_item = TextureObject(m1_name)
                    m1.AddChild(m1_item)
                    if isinstance(m1_items, dict):
                        m2_items = m1_items[m1_name]
                        if len(m2_items):
                            for m2_name in m2_items:
                                m2_item = TextureObject(m2_name)
                                m1_item.AddChild(m2_item)
    
        self._listView.listOfTexture.extend(res)
    
        # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW
        self._treegui.SetRoot(self._treegui, self._listView, None)
    
        return True
    

    Result:
    tree_view_menu.jpg

    The second question is How to interact with the htmlViewer area at the right of dialog from the my TreeView menu (Changing the htmlViewer file when clicking on a menu items).

    def Select(self, root, userdata, obj, mode):
        """
        Called when the user selects an element.
        """
        if mode == c4d.SELECTION_NEW:
            html_file = "file.html"
            #TestDialog()
            for tex in TextureObjectIterator(self.listOfTexture):
                tex.Deselect()
            obj.Select()
    

    Thanks

    posted in Cinema 4D SDK •
    TreeView Menu

    Hello,
    Is there a TreeView example to create a similar tree view menu like as the Cinema 4D help dialog?

    tree_view.png
    Thanks.

    posted in Cinema 4D SDK •
    RE: Dynamic HandleInfo.direction

    Hi @m_magalhaes,

    I used your suggestion and I replaced the +=. Yes is better, but it's always the same problem. I don't know how to explain the problem, and for that reason I have created this plugin object example. So the best way to understand the problem is by testing the example.

    I will try to explain roughly the problem:
    The handle point is pinned on child object of the main object plugin and this child object has a dynamic (position and rotation) that depend on the Pitch & Rotation values. So I must to dynamically adapt the info.direction depending on the position and rotation of the child object. And concerning this thread, this helped me to control the Pitch and Rotation via Handle but not the (Width, Height and Depth) values (of child object).

    At the moment, I guess I'll just use the SwapPoint() it doesn't have a perfect result but it's acceptable.

    Thanks.

    posted in Cinema 4D SDK •
    RE: Dynamic HandleInfo.direction

    Hi, @zipit

    Yes I'm searching a solution. I tried your solution but this does not work. the problem is with the handle point that not moving correctly (check the screen video above)

    I actually using the following method, but is too long and its works at 90%

    def GetAxis(self, pitch, rot):
            pitch = int(math.degrees(pitch))
            rot = int(math.degrees(rot))
            if -90 <= rot < -45 or 225 <= rot < 270:
                if -45 <= pitch < 45:
                    axis = 0 # +x
                elif -225 <= pitch < -135 or 135 <= pitch < 225:
                    axis = 1 # -z
                elif -135 <= pitch < -45:
                    axis = 3 # -y
                elif 45 <= pitch < 135 or -270 <= pitch < -225:
                    axis = 2 # +y
                else:
                    axis = 0 # +x
            elif -45 <= rot < 45:
                if -45 <= pitch < 45:
                    axis = 4 # +z
                elif -225 <= pitch < -135 or 135 <= pitch < 225:
                    axis = 5 # -z
                elif -135 <= pitch < -45:
                    axis = 13 # -y
                elif 45 <= pitch < 135 or -270 <= pitch < -225:
                    axis = 12 # +y
                else:
                    axis = 4 # +z
            elif 45 <= rot < 135:
                if -45 <= pitch < 45 or -225 <= pitch < -46:
                    axis = 11 # +x
                elif -225 <= pitch < -135 or 135 <= pitch < 225:
                    axis = 10 # -z
                elif 135 <= pitch < -45:
                    axis = 23 # -y
                elif 45 <= pitch < 135 or -270 <= pitch < -225:
                    axis = 22 # +y
                else:
                    axis = 1 # +x
            elif 135 <= rot < 225:
                if -45 <= pitch < 45:
                    axis = 15 # +x
                elif -225 <= pitch < -135 or 135 <= pitch < 225:
                    axis = 14 # -z
                elif -135 <= pitch < -45:
                    axis = 33 # -y
                elif 45 <= pitch < 135 or -270 <= pitch < -225:
                    axis = 32 # +y
                else:
                    axis = 5 # +x
            else:
                axis = 0
    
            return axis
    
    
       def SwapPoint(self, p, axis):
                if axis == 0 :
                    return c4d.Vector(-p.z, p.y, p.x)
                elif axis == 1 :
                    return c4d.Vector(p.z, -p.y, p.x)
                elif axis == 2 :
                    return c4d.Vector(-p.y, -p.z, p.x)
                elif axis == 3 :
                    return c4d.Vector(p.y, p.z, p.x)
                elif axis == 4 :
                    return c4d.Vector(-p.x, p.y, -p.z)
                elif axis == 5 :
                    return c4d.Vector(-p.x, -p.y, p.z)
                elif axis == 12 :
                    return c4d.Vector(-p.x, -p.z, -p.y)
                elif axis == 13 :
                    return c4d.Vector(-p.x, p.z, p.y)
                elif axis == 10 :
                    return c4d.Vector(-p.z, -p.y, -p.x)
                elif axis == 11 :
                    return c4d.Vector(p.z, p.y, -p.x)
                elif axis == 22 :
                    return c4d.Vector(p.y, -p.z, -p.x)
                elif axis == 23:
                    return c4d.Vector(-p.y, p.z, -p.x)
                elif axis == 14:
                    return c4d.Vector(p.x, -p.y, -p.z)
                elif axis == 15:
                    return c4d.Vector(p.x, p.y, p.z)
                elif axis == 32 :
                    return c4d.Vector(p.x, -p.z, p.y)
                elif axis == 33 :
                    return c4d.Vector(p.x, p.z, -p.y)
                return p
    
    axis = self.GetAxis(pitch, rotation)
    
    if handle_index == 0: # Width
        info.position = rot_mx * Vector(-size_x, 0, depth)
        info.direction = self.SwapPoint(info.direction, axis)
    

    Thanks.

    posted in Cinema 4D SDK •
    Dynamic HandleInfo.direction

    Hello,

    I'm searching if there a method to dynamically change the HandleInfo.direction depend on the rotation and pitch value of my object. I created the following object plugin example to illustrate exactly what I want to do.

    Screen video:
    dynamic_handleInfo.direction.gif

    pyp file:

    import c4d, os
    from c4d import utils, DescID, BaseObject, bitmaps, plugins, Vector, HandleInfo
    from math import radians
    
    PLUGIN_ID = 1055615
    
    class Osobject(plugins.ObjectData):
    
        def Init(self, op):
    
            self.fs_mg = c4d.Matrix()
            self.head_obj_h = 36
    
            data = op.GetDataInstance()
    
            data.SetFloat(c4d.OSOBJECT_SIZEX, 60.0)
            data.SetFloat(c4d.OSOBJECT_SIZEY, 50.0)
            data.SetFloat(c4d.OSOBJECT_DEPTH, 50.0)
            data.SetFloat(c4d.OSOBJECT_PITCH, radians(-30))
            data.SetFloat(c4d.OSOBJECT_ROTATION, radians(90))
    
            return True
    
        def GetVirtualObjects(self, op, hh):
            dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTY_MATRIX | c4d.DIRTY_DATA)
    
            if not dirty:
                return op.GetCache(hh)
    
            data = op.GetDataInstance()
    
            size_x = data.GetFloat(c4d.OSOBJECT_SIZEX)
            size_y = data.GetFloat(c4d.OSOBJECT_SIZEY)
            depth = data.GetFloat(c4d.OSOBJECT_DEPTH)
            pitch = data.GetFloat(c4d.OSOBJECT_PITCH)
            rotation = data.GetFloat(c4d.OSOBJECT_ROTATION)
    
            container = BaseObject(c4d.Onull)
            container.SetRelPos(Vector(0, 40, 0))
    
            bar = BaseObject(c4d.Ocylinder)
            bar.SetName("bar")
            bar.InsertUnder(container)
            bar.SetParameter(DescID(c4d.PRIM_CYLINDER_RADIUS), 1.5, c4d.DESCFLAGS_GET_0)
            bar.SetParameter(DescID(c4d.PRIM_CYLINDER_HEIGHT), 40, c4d.DESCFLAGS_GET_0)
            bar.SetParameter(DescID(c4d.PRIM_AXIS), 2, c4d.DESCFLAGS_GET_0)
            bar.SetRelPos(Vector(0, -20, 0))
    
            # Rotation Object
            rot_obj = BaseObject(c4d.Onull)
            rot_obj.SetRelRot(Vector(rotation, 0, 0))
            rot_obj.SetName("rotation")
            rot_obj.InsertUnder(container)
    
            # Pith Object
            pitch_obj = BaseObject(c4d.Onull)
            pitch_obj.SetRelRot(Vector(0, pitch, 0))
            pitch_obj.SetName("pitch")
            pitch_obj.InsertUnder(rot_obj)
    
            # Head Container
            head_container = BaseObject(c4d.Onull)
            head_container.SetName("head_container")
            head_container.InsertUnder(pitch_obj)
    
            # Head Object
            head_obj = BaseObject(c4d.Ocylinder)
            head_obj.SetName("head")
            head_obj.InsertUnder(head_container)
    
            head_obj.SetParameter(DescID(c4d.PRIM_CYLINDER_RADIUS), 10, c4d.DESCFLAGS_GET_0)
            head_obj.SetParameter(DescID(c4d.PRIM_CYLINDER_HEIGHT), self.head_obj_h, c4d.DESCFLAGS_GET_0)
            head_obj.SetParameter(DescID(c4d.PRIM_AXIS), 5, c4d.DESCFLAGS_GET_0)
    
            # depth Object
            depth_obj = BaseObject(c4d.Ocylinder)
            depth_obj.SetName("cyl")
            depth_obj.InsertUnder(head_container)
    
            depth_obj.SetParameter(DescID(c4d.PRIM_CYLINDER_RADIUS), 3, c4d.DESCFLAGS_GET_0)
            depth_obj.SetParameter(DescID(c4d.PRIM_CYLINDER_HEIGHT), depth, c4d.DESCFLAGS_GET_0)
            depth_obj.SetParameter(DescID(c4d.PRIM_AXIS), 5, c4d.DESCFLAGS_GET_0)
    
            depth_obj_pos = self.head_obj_h/2 + depth/2
            depth_obj.SetRelPos(Vector(0, 0, depth_obj_pos))
    
            # Front Surface Object
            fs_obj = BaseObject(c4d.Oplane)
            fs_obj.SetName("front_surface")
            fs_obj.InsertUnder(head_container)
            self.fs_mg = fs_obj.GetMg()
    
            fs_obj.SetParameter(DescID(c4d.PRIM_PLANE_WIDTH), size_x, c4d.DESCFLAGS_GET_0)
            fs_obj.SetParameter(DescID(c4d.PRIM_PLANE_HEIGHT), size_y, c4d.DESCFLAGS_GET_0)
            fs_obj.SetParameter(DescID(c4d.PRIM_PLANE_SUBW), 1, c4d.DESCFLAGS_GET_0)
            fs_obj.SetParameter(DescID(c4d.PRIM_PLANE_SUBH), 1, c4d.DESCFLAGS_GET_0)
            fs_obj.SetParameter(DescID(c4d.PRIM_AXIS), 5, c4d.DESCFLAGS_GET_0)
    
            fs_obj_pos = self.head_obj_h/2 + depth
            fs_obj.SetRelPos(Vector(0, 0, fs_obj_pos))
    
            return container
    
        def GetHandleCount(self, op):
            return 4
    
        def GetHandle(self, op, handle_index, info):
    
            data = op.GetDataInstance()
    
            size_x = data.GetFloat(c4d.OSOBJECT_SIZEX)
            size_y = data.GetFloat(c4d.OSOBJECT_SIZEY)
            depth = data.GetFloat(c4d.OSOBJECT_DEPTH)
            pitch = data.GetFloat(c4d.OSOBJECT_PITCH)
            rotation = data.GetFloat(c4d.OSOBJECT_ROTATION)
    
            size_x = size_x/2
            size_y = size_y/2
            depth = depth+self.head_obj_h/2
    
            mg = self.fs_mg
            pos = mg.off
            rot = utils.MatrixToHPB(mg, c4d.ROTATIONORDER_DEFAULT)
    
            rot_mx = utils.HPBToMatrix(rot)
            rot_mx.off += pos
    
            if handle_index == 0: # Width
                info.position = rot_mx * Vector(-size_x, 0, depth)
                info.direction = Vector(1, 0, 0)
            elif handle_index == 1: # Height
                info.position = rot_mx * Vector(0, size_y, depth)
                info.direction = Vector(0, 1, 0)
            elif handle_index == 2: # Depth
                info.position = rot_mx * Vector(0, 0, depth)
                info.direction = Vector(0, 0, 1)
    
            info.type = c4d.HANDLECONSTRAINTTYPE_LINEAR
    
        def SetHandle(self, op, handle_index, handle_position, info):
    
            handle_origin = HandleInfo()
            self.GetHandle(op, handle_index, handle_origin)
    
            data = op.GetDataInstance()
    
            size_x = data.GetFloat(c4d.OSOBJECT_SIZEX)
            size_y = data.GetFloat(c4d.OSOBJECT_SIZEY)
            depth = data.GetFloat(c4d.OSOBJECT_DEPTH)
            pitch = data.GetFloat(c4d.OSOBJECT_PITCH)
            rotation = data.GetFloat(c4d.OSOBJECT_ROTATION)
    
            size_x = size_x/2
            size_y = size_y/2
    
            value = (handle_position - handle_origin.position) * info.direction
    
            if handle_index == 0:
                op[c4d.OSOBJECT_SIZEX] -= value
            elif handle_index == 1:
                op[c4d.OSOBJECT_SIZEY] += value
            elif handle_index == 2:
                op[c4d.OSOBJECT_DEPTH] -= value
    
        def Draw(self, op, drawpass, bd, bh):
    
            if drawpass != c4d.DRAWPASS_HANDLES:
                return c4d.DRAWRESULT_SKIP
    
            data = op.GetDataInstance()
    
            size_x = data.GetFloat(c4d.OSOBJECT_SIZEX)
            size_y = data.GetFloat(c4d.OSOBJECT_SIZEY)
            depth = data.GetFloat(c4d.OSOBJECT_DEPTH)
            pitch = data.GetFloat(c4d.OSOBJECT_PITCH)
            rotation = data.GetFloat(c4d.OSOBJECT_ROTATION)
    
            size_x = size_x/2
            size_y = size_y/2
    
            bd.SetMatrix_Matrix(op, bh.GetMg())
            hitid = op.GetHighlightHandle(bd)
    
            for i in xrange(self.GetHandleCount(op)):
                bd.SetPen(c4d.GetViewColor(c4d.VIEWCOLOR_ACTIVEPOINT))
    
                info = HandleInfo()
    
                self.GetHandle(op, i, info)
                bd.DrawHandle(info.position, c4d.DRAWHANDLE_BIG, 0)
                bd.SetMatrix_Matrix(op, bh.GetMg())
    
            return c4d.DRAWRESULT_OK
    
    if __name__ == "__main__":
        icon = bitmaps.BaseBitmap()
        icon.InitWith(os.path.join(os.path.dirname(__file__), 'res', 'icon.tif'))
        plugins.RegisterObjectPlugin(PLUGIN_ID, 'Super Object', Osobject, 'osobject', c4d.OBJECT_GENERATOR, icon)
    
    

    And here the full example files: osobject.zip

    Thanks

    posted in Cinema 4D SDK •
    RE: Toggle bitmap button on .res file

    hi @m_magalhaes,

    Thank you much, that works.

    I have an another question concerning Description Resource, I don't know if I post it here or I must create a new post.

    Here is the code:

    GROUP
    {
        REAL MYOBJECT_PITCH { UNIT DEGREE; CUSTOMGUI REALSLIDER; MIN -360; MAX 360; STEP 1; }
        BITMAPBUTTON MYOBJECT_STRAIGHTEST_PITCH
        {
            SIZE 16;
            BUTTON;
            ALIGN_LEFT;
            ICONID1 5160;
        }
    
        REAL MYOBJECT_ROTATION { UNIT DEGREE; CUSTOMGUI REALSLIDER; MINSLIDER -90; MAXSLIDER 270; STEP 1; }
        STATICTEXT { JOINENDSCALE; }
    }
    

    And here screenshot of what I want to do:
    puch_icon_right.jpg
    Thanks

    posted in Cinema 4D SDK •
    Toggle bitmap button on .res file

    Hello,

    Is it possible to create a toggle bitmap button using only the .res file?
    I tried with the GetDDescription function its work well, but when I use .res file this doesn't work.
    Also, when I use the FORCE_SIZE on .res file I get an error.

    BITMAPBUTTON BUTTON_ID
    {
        TOGGLE;
        BUTTON;
        FORCE_SIZE 16;
        ICONID1 5160;
        ICONID2 5159;
    }
    

    Thanks

    posted in Cinema 4D SDK •
    RE: Change the default name of ID_OBJECTPROPERTIES

    @m_magalhaes said in Change the default name of ID_OBJECTPROPERTIES:

    DEFAULT 1;

    Thank you much.

    posted in Cinema 4D SDK •
    Change the default name of ID_OBJECTPROPERTIES

    Hello,

    I'm searching how to rename the default tab ID_OBJECTPROPERTIES "Object", I have created a new GROUP instead of it, this is works.
    But the problem now is: when I open or my plugin object the "Basic" tab is selected by default but I want to set the new GROUP as the default selected tab.

    objectproperties_name.jpg

    Thanks.

    posted in Cinema 4D SDK •
    RE: Best coding practices

    @zipit Thank you much.

    posted in Cinema 4D SDK •
    Best coding practices

    Hello,

    I'm cleaning my code and I have some of questions about the best practices to prevent any cinema 4d app crash.

    1 - Is it necessary to check if the object or tag it was created before inserting into the document?

    Example:

    obj = c4d.BaseTag(c4d.Onull)
    tag = c4d.BaseTag(c4d.Tdisplay)
    
    if not obj or not tag:
        return
        
    obj .InsertTag(tag)
    

    2- Is there a specific case to use the condition if value is None or if obj_or_tag is None instead of if not value or if not obj_or_tag

    I've always used the if not value method.

    Thanks

    posted in Cinema 4D SDK •
    RE: Colorize plugin object icon

    Thank you @m_adam, is there examples for previous cinema 4d versions (r19, r20)?

    posted in Cinema 4D SDK •
    Colorize plugin object icon

    Hello,

    I'm searching how can I dynamically colorize plugin icon like as the default C4D lights objects. I want to dynamically apply a color tint filter on my plugin object icon.

    def Message(self, node, type, data):
          if type == c4d.MSG_GETCUSTOMICON:
              color = node[c4d.MYOBJECT_COLOR]:
              icon = c4d.bitmaps.InitResourceBitmap(PLUGIN_ID)
    
              """width = icon.GetBw()
              height = icon.GetBh()
              
              for y in xrange(height) :
                for x in xrange(width) :
                    r,g,b = icon.GetPixel(x, y)
                    #icon.SetPixel(x, y, r, g, b)"""
                          
              data['bmp'] = icon
              data["w"] = icon.GetBw()
              data["h"] = icon.GetBh()
    
              data['filled'] = True
    

    Thanks.

    posted in Cinema 4D SDK •
    RE: Check if the object parameters has been changed

    Hi, Thank you @r_gigante, @zipit for your replies.

    The problem comes from the GetDDescription funtion because I use some of dynamic parameters on my objects.
    It is for this reason that op.IsDirty(c4d.DIRTY_DATA) returning True when I Move, Scale, Zoom or Rotate the perspective view.

    posted in Cinema 4D SDK •