SOLVED Context Problem

Hi im converting Materials using the Corona To C4D Plugin,
and im running into a strange problem, were my the context for my doc seems to go missing. But first thing first:

My setup:
I convert using the Cinema 4D exe as commandline, as the plugin otherwise does not seem to convert and store the information.

"Cinema 4D.exe" -nogui etc. etc..

This gives me very little commandline error output, making it very hard to debug, but its the only workaround i got for now. Se la vie.

I call my converter module giving it a doc reference and storing the document reference upon return

cac = CoronaAuraConverter.Converter(clone)
cloneResult = cac.main(clone, self, dst)
clone = cloneResult

In the converter submodule i process using the following code. This is because i can not seem to acess the converted materials until i saved and reload the document. This has been profen to work in a minimal sandbox example.

def main(self, doc, vuframeAuraInstanceRef, dst):

		#Conversion process copied from Sandbox

		tempORaryFilePath = dst, "tempStorageForMaterialDrop.c4d")
		LogWithTimestamp("TempoaryFilePath " + tempORaryFilePath)
		documents.SaveDocument(doc, tempORaryFilePath, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, c4d.FORMAT_C4DEXPORT)

		newDoc = Tools.loadActiveDocumentFrom(tempORaryFilePath)
		allMats = newDoc.GetMaterials()
		for mat in allMats:
			LogWithTimestamp("Storing Material Standard Info:" + mat.GetName())
                         #Doing work with the loaded materials - this work

		return doc

The problem:

Upon return working with the returned old doc reference seems to fail.
I tried to refresh it with

doc = documents.GetActiveDocments()

assumption being its some context reference going stale and getting gcc or similar.

Anyone any idea were i did go wrong. Also a way to get the standard output beyond 25 kb by g_logfile="c4dconversion.log" would be greatly appreciated.

Regards FSS

PS: Is there a way to buy SDK-Team Support tickets?

PS: Just for completness, not relevant as it loads the document

def loadActiveDocumentFrom(src):
	print "DEBUG: file exists :" + str(os.path.exists(src))
	load = documents.LoadFile(src)
	if not load:
		LogWithTimestamp( "Source File could not be loaded: " + src)
		raise FileNotFoundError("Source file at path " +src + " not found")

	doc = documents.GetActiveDocument()
	if doc is None:
		LogWithTimestamp( "Could not get active document")
		return False

	return doc
This post is deleted!
This post is deleted!
This post is deleted!

Hello @fss,

Thank you for reaching out to us. Please note that there are certain limitations to the support we provide and the form we require:

  1. Diary style threads are not allowed, please put all relevant information into one posting. If you uncover information after you made your initial posting, please edit that posting instead of answering your own thread. When we have answered, you can of course make a new posting in that topic, but the number of postings in a topic should always be as small as possible. Otherwise the thread can become hard to read and answer for us.
  2. As stated in our forum guidelines, we cannot debug code for users. This applies to your case, because you have quite a bit of custom modules there which you do not show and even if you would, it would be out of scope of support, as we cannot go bug hunting in larger stretches of code, i.e., debug code for users.

With that being said, I am not sure if you have solved your problem yourself by now. But there are a few things I would point out:

  1. You should use c4dpy if you want to run Python code in a GUIless Cinema 4D environment.
  2. You never explain how your code is triggered. I assume it is a plugin tied into PluginStart()? Be aware that depending on the plugin message, Cinema 4D might not yet have booted fully, you should not rely on the active document and similar things before C4DPL_STARTACTIVITY has been emitted. The earlier you are in the boot process, the less libraries and systems will work properly, up to the point where the c4d and maxon packages have not been initialized.
  3. A GUI-less Cinema 4D has consequences, some functionalities will not work properly, as they rely on a GUI being present (and the code then might halt because of that).
  4. Loading a document, getting all materials in it, modifying them, and then saving the document should however work fine. We cannot make any statements about third party libraries as Corona and their commands.

Finally, you report the doc 'reference seems to fail.' Fail could mean here multiple things, but from the whole setting of your question is would assume that you are encountering a dead atom. The Python object cannot be garbage collected before its reference count goes to zero, just as any other Python object. But this c4d.documents.BaseDocument object called doc is just the frontend for a C++ object of matching type in the backend. A pattern as the following can be dangerous:

def foo(typeID):
    node = c4d.BaseList2D(typeID)
    return node

As node is not bound to any scope after the scope of foo has been left and cause Cinema 4D Python bindings to deallocate the C++ object wrapped by node. This severing of the C++ to Python binding of an object can be tested with C4DAtom.IsAlive(). There are also other cases where an object can die, as Cinema 4D often reallocates objects in the background. Since a BaseDocument is a BaseList2D, is a GeListNode, is a C4DAtom, it can also die. There are no diagrams for the life cycle of a BaseDocument. Many things in the backend of our API can decide to reallocate an object.


Thank you for the answer @ferdinand . Sorry for the decay of the follow up posts, im used to posting all attempted solutions, so that future readers have a guide.

We solved the problem by converting in a seperate Plugin call and it seems the legacy code im working on, "accidentally" reduced the context switch stale objects, by regularly re-storing the document refrence from a old reference kept in main. Your answers have been very useful and highlight important concepts developers should be well aware off. Thanks gain.

Thanks for the update!