Long Script Loops_Threading?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/02/2012 at 14:30, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   12 
    Platform:   Windows  ;   
    Language(s) :     C++  ;   PYTHON  ;

    ---------
    I have a script that creates splines from the selected polygon object.
    I basically just wrote my own version of the ExplodeSegments command. But it creates splines instead of polygon objects.

    The problem is. Depending on how many splines I'm creating. It can take several minutes for this script to finish running. And for some reason the spinning bar that I've written into the code stops animating after 10-15 seconds. And C4D acts like it's locked up and not responding.
    But if I let the script finish...Eventually it finished and everything goes as it should.

    Obviously this is bad. And I need to make C4D handle this better.
    I've tried using StopAllThreads() in various places. And it doesn't seem to help.
    How can I make scripts like this run better. And not lock up the UI and the spinning progress bar?

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/02/2012 at 17:42, xxxxxxxx wrote:

    You would need to spawn a separate thread and do your work from it since the default one is the main thread (which is why C4D locks up).



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/02/2012 at 19:27, xxxxxxxx wrote:

    I've never worked with threads before. Totally green.
    Any tips that might help me at least get started on it?

    I'm not seeing much in the SDK or the docs about threading to learn how to do it.
    And I'm not finding anything at all about threading scripts or command data plugins.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 12/02/2012 at 03:26, xxxxxxxx wrote:

    Hi Scott, threading in Python is easy, but I haven't worked with it in C/C++ yet.

    import threading  
    class MyThread(threading.Thread) :  
      def run(self) :  
          "do what you want to do in the thread, here."  
      
    thread = MyThread()  
    thread.start()  
    # process stuff while the thread is doing his work  
    thread.join() # waits until the thread finished it's work
    

    An alternative would be

    def myThreadedFunction() :  
            "do what you want to do in the thread, here."  
      
    thread = threading.Thread(target=myThreadedFunction)  
    # ...
    

    You can also overwrite the constructor an add your custom arguments.
    Here's more about threading: http://docs.python.org/library/threading.html



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 12/02/2012 at 06:22, xxxxxxxx wrote:

    In C++, you need two parts, a controller class and a thread class derived from Thread.  Here are simplified header and source for each:

    ////////////////////////////////////////////////////////////////  
    // ControlThread.h  
    ////////////////////////////////////////////////////////////////  
      
    #ifndef _CONTROLTHREAD_H_  
    #define _CONTROLTHREAD_H_  
      
    #include "c4d.h"  
    #include "GMPThread.h"  
      
    // CLASS: ControlThread  
    class ControlThread : public Thread  
    {  
      public:  
          // Data  
          // - MP Thread related  
          LONG                cpu_count;  
    #ifdef    C4D_R12  
          MPThreadPool        mp;  
    #else  
          MPThread            mp;  
    #endif  
          GMPThread            thread[MAX_THREADS];  
          Thread*                tlist[MAX_THREADS];  
      
          // Methods  
          ControlThread();  
          ~ControlThread();  
          // - Thread  
          void                Main();  
          const CHAR*            GetThreadName() { return "ControlThread"; }  
          // - ControlThread  
          Bool                Initialize();  
    };  
      
    #endif //_CONTROLTHREAD_H_
    
    ////////////////////////////////////////////////////////////////  
    // ControlThread.cpp  
    ////////////////////////////////////////////////////////////////  
      
    #include "ControlThread.h"  
      
    // METHODS: ControlThread ======================================================================================================  
    // Constructor  
    //*---------------------------------------------------------------------------*  
    ControlThread::ControlThread()  
    //*---------------------------------------------------------------------------*  
    {  
    }  
    // Destructor  
    //*---------------------------------------------------------------------------*  
    ControlThread::~ControlThread()  
    //*---------------------------------------------------------------------------*  
    {  
    }  
    // Thread.Main  
    // - This is the Multi-Processor Control Thread  
    //*---------------------------------------------------------------------------*  
    void ControlThread::Main()  
    //*---------------------------------------------------------------------------*  
    {  
    #ifdef    C4D_R11 // or later  
      if (!mp.Start(THREADPRIORITY_NORMAL))    return;  
    #else  
      if (!mp.Start())    return;  
    #endif  
      mp.Wait();  
    }  
    // ControlThread.Initialize  
    //*---------------------------------------------------------------------------*  
    Bool ControlThread::Initialize()  
    //*---------------------------------------------------------------------------*  
    {  
      // Get this once and for task-separation purposes  
      cpu_count =                    GeGetCPUCount();  
      for (LONG i = 0L; i != cpu_count; ++i)  
      {  
          tlist[i] =    &thread[i];  
          thread[i].Initialize(this);  
      }  
      
      // Initialize MPThread for later use  
      if (!mp.Init(*this,cpu_count,tlist))    return GePrint("ControlThread.Initialize.mp.Init()");  
      
      return TRUE;  
    }  
    
    ////////////////////////////////////////////////////////////////  
    // GMPThread.h  
    ////////////////////////////////////////////////////////////////  
      
    #ifndef _GMPTHREAD_H_  
    #define _GMPTHREAD_H_  
      
    #include "c4d.h"  
    #include "GMPSupport.h"  
      
    // Predefines for GMPThread  
    class ControlThread;  
      
    // CLASS: GMPThread  
    class GMPThread : public Thread  
    {  
      private:  
          // Data  
          ControlThread*        cthread;  
      public:  
          // Data  
      
          // Methods  
          GMPThread();  
          ~GMPThread();  
          // - Thread  
          void                Main();  
          const CHAR*            GetThreadName();  
          // - GMPThread  
          Bool                Initialize(ControlThread* ct);  
    };  
    #endif //_GMPTHREAD_H_  
    
    ////////////////////////////////////////////////////////////////  
    // GMPThread.cpp  
    ////////////////////////////////////////////////////////////////  
      
    #include "GMPThread.h"  
    #include "ControlThread.h"  
      
    // METHODS: GMPThread ======================================================================================================  
    // Constructor  
    //*---------------------------------------------------------------------------*  
    GMPThread::GMPThread()  
    //*---------------------------------------------------------------------------*  
    {  
    }  
    // Destructor  
    //*---------------------------------------------------------------------------*  
    GMPThread::~GMPThread()  
    //*---------------------------------------------------------------------------*  
    {  
    }  
    // Thread.GetThreadName  
    //*---------------------------------------------------------------------------*  
    const CHAR* GMPThread::GetThreadName()  
    //*---------------------------------------------------------------------------*  
    {  
      return "GMPThread";  
    }  
    // GMPThread.Initialize  
    //*---------------------------------------------------------------------------*  
    Bool GMPThread::Initialize(ControlThread* ct)  
    //*---------------------------------------------------------------------------*  
    {  
      // Store ControlThread  
      cthread =                ct;  
      return TRUE;  
    }  
    // Thread.Main  
    // - This is the Single-Processor Thread  
    //*---------------------------------------------------------------------------*  
    void GMPThread::Main()  
    //*---------------------------------------------------------------------------*  
    {  
      // Do your thing! :)  
    }  
    

    Initialize the threads through the controller class - only needs to be done once

    // - Main Multi-Processor Thread  
      if (!cthread.Initialize())            return ErrorException::Throw(GeLoadString(GREERR_GENERAL), "GreeblerObj.Init.cthread");
    

    Start the thread or threads running:

    // - Begin Multiprocessing  
      cthread.Start(THREADMODE_SYNCHRONOUS);  
    

    A thread ends its active processing when it exits its Main() method.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 12/02/2012 at 08:22, xxxxxxxx wrote:

    Thanks a ton guys.🍺
    I'll take a look at your examples today and try to learn how it all works.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 13/02/2012 at 01:33, xxxxxxxx wrote:

    You can also take a look at the documentation of C4DThread class in c4d.threading module, there's a simple example showing how to use it.


Log in to reply