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.