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

    How to get mouse drag info from external through Python API?

    Cinema 4D SDK
    2
    10
    1.9k
    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.
    • L
      lotusab12
      last edited by m_adam

      Hi all, recently I need to finish a tiny plugin for C4D, the function is when I drag a file (mov jpeg c4d obj etc.) from external like windows explorer, or drag a path into C4D main window, the plugin will do something in C4D according to the file format extension, atthe beginning I want to open up a udp port, but I think this is not the best way, so if I want to write a callback detecting mouse drag from external, how to achieve that in python? I am quite new to c4d, I am a Maya TD...Thanks

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

        hi @lotusab12, first all welcome in the plugincafe community.

        It's not possible to register a callback to such a global event in Cinema 4D. You could receive drag event from your own c4d.gui.GeDialog but that's it.
        Since you want to open a UDP port, I think it's probable that you want to run a server? If it's the case you may need to create a MessageData Plugin, but I will elaborate if it's the case just tell me.

        So your first need is to support a new file format, you can do this by creating a SceneLoader Plugin. Find an implementation example in py-xample_loader.

        When a user drops a file into Cinema 4D, all registered SceneLoaderData will be called. Since you don't really want to load a new scene (if I'm right), in your SceneLoaderData.Identify you can check if the file matches your pattern open your UDP port and return False.

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

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        L 1 Reply Last reply Reply Quote 1
        • L
          lotusab12
          last edited by

          This post is deleted!
          1 Reply Last reply Reply Quote 0
          • L
            lotusab12 @m_adam
            last edited by

            @m_adam said in How to get mouse drag info from external through Python API?:

            hi @lotusab12, first all welcome in the plugincafe community.

            It's not possible to register a callback to such a global event in Cinema 4D. You could receive drag event from your own c4d.gui.GeDialog but that's it.
            Since you want to open a UDP port, I think it's probable that you want to run a server? If it's the case you may need to create a MessageData Plugin, but I will elaborate if it's the case just tell me.

            So your first need is to support a new file format, you can do this by creating a SceneLoader Plugin. Find an implementation example in py-xample_loader.

            When a user drops a file into Cinema 4D, all registered SceneLoaderData will be called. Since you don't really want to load a new scene (if I'm right), in your SceneLoaderData.Identify you can check if the file matches your pattern open your UDP port and return False.

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

            WoW, your feedback is full of detail! Awosome, really thanks for your kind and rapid reply, first of all I will just forget about open a UDP port, I will write a plugin first and follow your steps and read the document, next if I met any problem, I will ask you for future help, anyway thanks a lot man!

            Best
            Javier

            L 1 Reply Last reply Reply Quote 0
            • L
              lotusab12 @lotusab12
              last edited by lotusab12

              @lotusab12 said in How to get mouse drag info from external through Python API?:

              @m_adam said in How to get mouse drag info from external through Python API?:

              hi @lotusab12, first all welcome in the plugincafe community.

              It's not possible to register a callback to such a global event in Cinema 4D. You could receive drag event from your own c4d.gui.GeDialog but that's it.
              Since you want to open a UDP port, I think it's probable that you want to run a server? If it's the case you may need to create a MessageData Plugin, but I will elaborate if it's the case just tell me.

              So your first need is to support a new file format, you can do this by creating a SceneLoader Plugin. Find an implementation example in py-xample_loader.

              When a user drops a file into Cinema 4D, all registered SceneLoaderData will be called. Since you don't really want to load a new scene (if I'm right), in your SceneLoaderData.Identify you can check if the file matches your pattern open your UDP port and return False.

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

              WoW, your feedback is full of detail! Awosome, really thanks for your kind and rapid reply, first of all I will just forget about open a UDP port, I will write a plugin first and follow your steps and read the document, next if I met any problem, I will ask you for future help, anyway thanks a lot man!

              Best
              Javier

              import c4d
              import socket
              from c4d.threading import C4DThread
              
              class A(C4DThread):
                  sock = socket.socket(socket.AF_INIT, socket.SOCK_DGRAM)
                  
                  def Main(self):
                      self.sock.bind(("localhost", 20015))
                      while(True):
                          data, addr = self.sock.recvfrom(1024)
              
                  def End(self):
                      self.sock.close()
              
              if __name__ == "__main__":
                  thread = A()
                  thread.Start()
              

              I have this piece of code in my simple plugin, my problem is since a while loop is keep running, after I close C4D, the cinema4d.exe is still runing behind the hood, so how can I kill this thread properly after I close Cinema4D application? Thanks.

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

                Hi @lotusab12

                In such a thread you need to call TestBreak() in order to test if Cinema 4D tell your thread to stop.
                This will give us something like:

                def Main(self):
                    self.sock.bind(("localhost", 20015))
                    while(True):
                        if self.TestBreak():
                            server.close()
                            self.End()
                
                        data, addr = self.sock.recvfrom(1024)
                
                def End(self):
                    self.sock.close()
                

                Another and probably safer version also is to define a timeout this way you can shut down your server if nothing happens since a given time lapse.

                Cheers,
                Maxime.

                MAXON SDK Specialist

                Development Blog, MAXON Registered Developer

                L 2 Replies Last reply Reply Quote 0
                • L
                  lotusab12 @m_adam
                  last edited by

                  @m_adam said in How to get mouse drag info from external through Python API?:

                  Hi @lotusab12

                  In such a thread you need to call TestBreak() in order to test if Cinema 4D tell your thread to stop.
                  This will give us something like:

                  def Main(self):
                      self.sock.bind(("localhost", 20015))
                      while(True):
                          if self.TestBreak():
                              server.close()
                              self.End()
                  
                          data, addr = self.sock.recvfrom(1024)
                  
                  def End(self):
                      self.sock.close()
                  

                  Another and probably safer version also is to define a timeout this way you can shut down your server if nothing happens since a given time lapse.

                  Cheers,
                  Maxime.

                  Thanks man, I will give it a try!

                  1 Reply Last reply Reply Quote 0
                  • L
                    lotusab12 @m_adam
                    last edited by lotusab12

                    @m_adam said in How to get mouse drag info from external through Python API?:

                    Hi @lotusab12

                    In such a thread you need to call TestBreak() in order to test if Cinema 4D tell your thread to stop.
                    This will give us something like:

                    def Main(self):
                        self.sock.bind(("localhost", 20015))
                        while(True):
                            if self.TestBreak():
                                server.close()
                                self.End()
                    
                            data, addr = self.sock.recvfrom(1024)
                    
                    def End(self):
                        self.sock.close()
                    

                    Another and probably safer version also is to define a timeout this way you can shut down your server if nothing happens since a given time lapse.

                    Cheers,
                    Maxime.

                    import c4d
                    import socket
                    from c4d.threading import C4DThread
                    
                    class A(C4DThread):
                        sock = socket.socket(socket.AF_INIT, socket.SOCK_DGRAM)
                        
                        def Main(self):
                            self.sock.bind(("localhost", 20015))
                            while(True):
                                if self.TestBreak():
                                    self.End()
                    
                                data, addr = self.sock.recvfrom(1024)
                    
                        def End(self):
                            self.sock.close()
                    
                    if __name__ == "__main__":
                        thread = A()
                        thread.Start()
                    

                    Hi Maxime, I tried TestBreak(), above are my code, but after I close Cinema4D, CINEMA4D.exe was still hunging up in Windows Task Monitor, it can not be killed properly, I tried to remove line "data, addr = self.sock.recvfrom(1024)" and add a "break" in "if TestBreak():", CINEMA4D.exe can be killed in Task Monitor, so please help me pointing out where I was wrong, it seems something interup with thread itself?

                    PS: I don't know what does the line "server.close()" in your code mean, does it equal to self.sock.close()?

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

                      Hi sorry about the confusion of server.close I was referring to self.sock.close.

                      After some tests the main issue with your code is currently recvfrom is blocking, meaning until it receives something all the code is blocked, so TestBreak is never called and the thread never ends.

                      So using timeout solve the issue.

                      import c4d
                      import socket
                      
                      
                      class A(c4d.threading.C4DThread):
                          sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                          end = False
                          
                          def Main(self):
                                  
                              self.sock.bind(("localhost", 20014))
                              while True:
                      
                                  # use timeout to check for TestBreak()
                                  try:
                                      self.sock.settimeout(1.0)
                                      self.sock.listen(1)
                                      conn, addr = self.sock.accept()
                      
                                      # connection  
                                      print('Connection address:' + str(addr))
                                  
                                      data = conn.recv(BUFFER_SIZE)
                                      if not data:
                                          print("Got no data.")
                                          break
                                      else:
                                          print("received data:" + str(data))
                                          print str(data)
                                          self._data = str(data)
                                          # DO SOMETHING
                                  
                                      conn.close()
                      
                                  # timeout
                                  except:
                                      if self.TestBreak():
                                          self.sock.close()
                                          self.End()
                                          return
                                      continue
                      
                              self.sock.close()
                      
                      
                      if __name__ == "__main__":
                          threadedServer = A()
                          threadedServer.Start()
                      

                      Cheers,
                      Maxime.

                      MAXON SDK Specialist

                      Development Blog, MAXON Registered Developer

                      L 1 Reply Last reply Reply Quote 0
                      • L
                        lotusab12 @m_adam
                        last edited by

                        @m_adam said in How to get mouse drag info from external through Python API?:

                        Hi sorry about the confusion of server.close I was referring to self.sock.close.

                        After some tests the main issue with your code is currently recvfrom is blocking, meaning until it receives something all the code is blocked, so TestBreak is never called and the thread never ends.

                        So using timeout solve the issue.

                        import c4d
                        import socket
                        
                        
                        class A(c4d.threading.C4DThread):
                            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                            end = False
                            
                            def Main(self):
                                    
                                self.sock.bind(("localhost", 20014))
                                while True:
                        
                                    # use timeout to check for TestBreak()
                                    try:
                                        self.sock.settimeout(1.0)
                                        self.sock.listen(1)
                                        conn, addr = self.sock.accept()
                        
                                        # connection  
                                        print('Connection address:' + str(addr))
                                    
                                        data = conn.recv(BUFFER_SIZE)
                                        if not data:
                                            print("Got no data.")
                                            break
                                        else:
                                            print("received data:" + str(data))
                                            print str(data)
                                            self._data = str(data)
                                            # DO SOMETHING
                                    
                                        conn.close()
                        
                                    # timeout
                                    except:
                                        if self.TestBreak():
                                            self.sock.close()
                                            self.End()
                                            return
                                        continue
                        
                                self.sock.close()
                        
                        
                        if __name__ == "__main__":
                            threadedServer = A()
                            threadedServer.Start()
                        

                        Cheers,
                        Maxime.

                        Awosome, the whole script works very well now, thanks man, you help me quite a lot! mua~

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