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
    1. Maxon Developers Forum
    2. alexandre.dj
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 5
    • Best 0
    • Controversial 0
    • Groups 0

    alexandre.dj

    @alexandre.dj

    0
    Reputation
    1
    Profile views
    5
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    alexandre.dj Unfollow Follow

    Latest posts made by alexandre.dj

    • RE: Defer Modifying Menus to the Main Thread

      @ferdinand
      Just a quick update that using an event message to force update the view after creating the menus is working great.

      c4d.EventAdd(c4d.EVMSG_CHANGE)
      
      posted in Cinema 4D SDK
      alexandre.djA
      alexandre.dj
    • RE: Defer Modifying Menus to the Main Thread

      @alexandre-dj
      Here is my code. I created a BuildBufferedMenus class inheriting from threading.Thread and starting a counter running for 3 seconds.

      Everytime a C4DPL_BUILDMENU message is emitted, I reset the counter to 0.

      When the counter reaches 3 seconds, it builds the menus.

      However, as discussed, the c4d.gui.UpdateMenus() call in my exit() function updates the menus but does not update the view. I cannot see them until I change the layout (minimize the window, change layout, or the like).

      In my latest version, I added the menus_updated property flag to let the main thread know that my menus are built and that I need the layout to update. Hence my previous question about sending a message to the main thread or checking in any method occuring regularly that my menus need an update.

      class BuildBufferedMenus(threading.Thread):
          """ Build c4d menus introducing a delay to deal with multiple builds (R26) """
      
          def __init__(self, max_time=3):
              super().__init__()
              self.max_time = max_time
              self.current_time = 0
              self.is_running = False
              self._menus_updated = False
      
          def build_menus(self):
              """ Method called from the plugin message to start or reset the timer """
              # start timer if thread not running
              if not self.is_running:
                  self.start()
              # reset timer if thread is running
              else:
                  self.reset()
      
          def run(self):
              """ Timer loop """
              self.is_running = True
              while self.current_time < self.max_time:
                  self.current_time += 1
                  time.sleep(1)
              # reinit timer variables and exit thread at the end
              self.is_running = False
              self.current_time = 0
              self.exit()
      
          def reset(self):
              """ Reset Timer """
              self.current_time = 0
      
          def exit(self):
              """ Exit timer """
              enhanceMainMenu()  # adds my custom menus
              c4d.gui.UpdateMenus()
              self._menus_updated = True
      
          @property
          def menus_updated(self):
              return self._menus_updated
      
          @menus_updated.setter
          def menus_updated(self, value):
              if not isinstance(value, bool):
                  raise ValueError(f'{value} should be of type bool (True or False)')
              self._menus_updated = value
      
      # create class instance
      buffered_menus = BuildBufferedMenus()
      
      def myPluginMessage(id, data):
          if id==c4d.C4DPL_BUILDMENU:
              buffered_menus.build_menus()
      
      posted in Cinema 4D SDK
      alexandre.djA
      alexandre.dj
    • RE: Defer Modifying Menus to the Main Thread

      Thank you Ferdinand and sorry about breaking the forum's rules. I will be more careful in the future and open a new ticket if needed.

      posted in Cinema 4D SDK
      alexandre.djA
      alexandre.dj
    • Defer Modifying Menus to the Main Thread

      @ferdinand Thanks again for your help.

      I managed to build our menus using a simple timer in the end, so it is waiting for the last c4d.C4DPL_BUILDMENU message before triggering the build.

      I am however using a separate thread for this, and I encounter the issue you are mentionning in your answer, that is my menus are built but not showing up, as I am calling c4d.gui.UpdateMenus() from that separate thread, whereas it needs to be called from the main thread.

      Is there a c4d method to send code to execute int he main thread? I can't find anything like this in the documentation. Or can I simply trigger a menu update (using a simple flag set to true when the side thread is done) from the main thread? There must be an Update() function somewhere that is run every few seconds?


      edit: forked from building-menus-with-c4dpl_buildmenu-in-s26 by @ferdinand due to being off topic.

      posted in Cinema 4D SDK python s26
      alexandre.djA
      alexandre.dj
    • RE: Building menus with C4DPL_BUILDMENU in S26+

      Hello Ferdinant. I'm following up on this ticket that I opened last November.

      First of all thank you for your help. I am running some tests to make sure that our custom menus are built only once when starting R26. If possible, I would like to still use the C4DPL_BUILDMENU event and simply check if my menus already exist. I know all menus in C4D have their own id, so this should be an easy check.

      However, I encouter a first issue:
      When firing c4d.gui.GetMenuResource("M_EDITOR") to Get the whole menu of Cinema 4D (as you mention in your code here) I get a different address every time:

      >>> c4d.gui.GetMenuResource("M_EDITOR")
      <c4d.BaseContainer object at 0x000001B406C86580>
      >>> c4d.gui.GetMenuResource("M_EDITOR")
      <c4d.BaseContainer object at 0x000001B406CA6A40>
      >>> c4d.gui.GetMenuResource("M_EDITOR")
      <c4d.BaseContainer object at 0x000001B406C88C80>
      

      So when I use c4d.gui.SearchMenuResource(main_menu_ressource, my_custom_menu) to check if my custom menu is part of the main menu, this always return False, as the address of the main_menu object changes.

      Could you please enlighten me on this?

      posted in Cinema 4D SDK
      alexandre.djA
      alexandre.dj