R18 export Alembic thread error

On 27/04/2017 at 09:27, xxxxxxxx wrote:

Hi,

I have a problem in R18 (works fine in R17), when trying to export/save documents to alembic file. (SaveDocument). When using command documents.SaveDocument(), c4d returns True, but it doesn't export/save anything to disk...

I usually execute my command...

documents.SaveDocument(documents.GetActiveDocument(), DEST_FILE, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, ABC_EXPORTER_ID)

... from an external application, communicating with C4D using OSC mudules.

Following that post, which is similar to my problem, I'm trying to export from within another thread (as suggested).
https://plugincafe.maxon.net/topic/9881/13306_cannot-export-to-fbx-from-command-line&KW=saveDocument&PID=52663#52663

So... to test it out, running in C4D Script Manager, here's what I am trying...

import c4d
from c4d import documents, threading
import sys
  
  
ABC_EXPORTER_ID = 1028082
  
DEST_FILE = "C:/temp/C4dExport_v001.abc"
DEST_FILE2 = "C:/temp/C4dExport_v002.abc"
  
class ExportThread(threading.C4DThread) :
  
    def __init__(self, doc) :
        self.status = False
    
    def Main(self) :
        # Export document to ABC
        self.status = documents.SaveDocument(documents.GetActiveDocument(), DEST_FILE, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, ABC_EXPORTER_ID)
        c4d.EventAdd() 
  
    def GetStatus(self) :
        return self.status
  
  
def ExportABC() :
    
    # thread = ExportThread(clone)
    thread = ExportThread(doc)
  
    thread.Start()       # Start thread
    thread.End()         # Then end it but wait until it finishes
    
    # Retrieve export status and return it
    status = thread.GetStatus()
    return status
  
print 'EXPORT ABC THREADED: ' , ExportABC()
print 'EXPORT ABC NOT THREADED: ', documents.SaveDocument(documents.GetActiveDocument(), DEST_FILE2, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, ABC_EXPORTER_ID)

Testing to export both from another thread, and from current, c4d returns 'True', from both.
But, only one file is created to disk (the not threaded one), while the other one is not created.

Any idea about what went wrong?

On 28/04/2017 at 04:47, xxxxxxxx wrote:

Hi,

there are a few issues with your code.

a) You are not allowed to call EventAdd() from a thread other than the main thread. See Threading Information in the docs. So, you'd want to move that call to your main function after thread.End().

b) You need to wait for your thread to get the work done. You probably misunderstood the docs here. If C4DThread.End() is called with default parameter True, it does not mean, End() will wait for the thread to finish all its work. It will set the break condition in any case, but you have the guarantee, that the thread actually finished, when End() returns. This way you can be sure, the thread won't touch any resources anymore, you might want to free. While calling End(False) will return immediately (is faster), but the thread may still be running in background until it hits its break condition and then exits and gets cleaned up. Faster, but your code needs to be aware of this.
Instead you want to use C4DThread.Wait().

On 28/04/2017 at 07:51, xxxxxxxx wrote:

Hey Andreas,

thanks a lot for the informations! It'll be very useful.

However, I tried that code, with the suggestions added, in both R17 and R18 (R18.041). It works just fine in R17 (both threaded and not threaded abc are exported). In R18, the 'threaded' alembic is never exported, while the function still returns True, the 'NOT' threaded alembic exports well...

Do you have the same results on your side?

import c4d
from c4d import documents, threading
import sys
  
  
ABC_EXPORTER_ID = 1028082
  
DEST_FILE = "C:/temp/C4dExport_v001.abc"
DEST_FILE2 = "C:/temp/C4dExport_v002.abc"
  
class ExportThread(threading.C4DThread) :
  
    def __init__(self, doc) :
        self.status = False
        self.doc = doc
    
    def Main(self) :
        # Export document to ABC
        self.status = documents.SaveDocument(self.doc, DEST_FILE, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, ABC_EXPORTER_ID)
    
    def GetStatus(self) :
        return self.status
  
  
def ExportABC() :
    
    doc = documents.GetActiveDocument()
    thread = ExportThread(doc)
  
  
    thread.Start()       # Start thread   
    thread.Wait(True)
    
    status = thread.GetStatus()
    print 'EXPORT ABC THREADED STATUS: ',  status
  
ExportABC()
print 'EXPORT ABC NOT THREADED: ', documents.SaveDocument(documents.GetActiveDocument(), DEST_FILE2, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, ABC_EXPORTER_ID)

On 16/05/2017 at 09:25, xxxxxxxx wrote:

Further discussion of export in a custom thread can be found in this follow-up thread.