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.