UNSOLVED import presets and be reversible

I have been using commonly what is

c4d.documents.MergeDocument(doc,'preset://direction',c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS)

that does not present errors when reversing its action, but an error that I realized is that if I try to return to when I had the preset (for this the preset had texture) it doesn't load its texture or if it does load I had to go back several times, does anyone know why this happens?

Hello @jh23,

thank you for reaching out to us. I unfortunately do struggle a bit with understanding your question.

What I get is that you are merging two documents and that the Undo-stack of the merged document is not what you would expect it to be. You seem to have to hit Undo multiple times ('I had to go back several times') where you expect only one undo stack. It is extremely hard to give a conclusive answer based on what I do understand from your question, so I would propose that you kindly would reiterate what you are trying to do and what you expect to happen.

In the meantime, I can only offer two proposals:

  • Check that feature in the application to merge two documents, i.e., File|Merge Project, does behave diffrently than your code does for the respective documents. If it does not, then this topic here is a feature request and not a coding question which must be directed towards customer support.
  • Depending on what you are trying to do, using the flags c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS | c4d.SCENEFILTER_MERGESCENE instead of just the two you are using could help.

Cheers,
Ferdinand

To be honest, I don't even know what happens, the line of code that I put is all the code there is, even so, I admit that I could not explain myself well.
I tried what you proposed and didn't see much of a difference, but trying a few things I solved my problem as follows

Code before correcting

import c4d
from c4d import gui
def main():
    c4d.documents.MergeDocument(doc,'preset://name',c4d.SCENEFILTER_MATERIALS | c4d.SCENEFILTER_OBJECTS))
if __name__=='__main__':
    main()

Corrected code

import c4d
from c4d import gui
def main():
    doc.StartUndo()
    doc.AddUndo(c4d.UNDOTYPE_NEW, c4d.documents.MergeDocument(doc,'preset://name',c4d.SCENEFILTER_MATERIALS | c4d.SCENEFILTER_OBJECTS))
    doc.EndUndo()
    c4d.EventAdd()
if __name__=='__main__':
    main()

Even so, I would like to investigate your proposal and I really appreciate your help.

Hello @jh23,

you wrote:

Corrected code:

import c4d
from c4d import gui
def main():
    doc.StartUndo()
    doc.AddUndo(c4d.UNDOTYPE_NEW, c4d.documents.MergeDocument(doc,'preset://name',c4d.SCENEFILTER_MATERIALS | c4d.SCENEFILTER_OBJECTS))
    doc.EndUndo()
    c4d.EventAdd()
if __name__=='__main__':
    main()

This will not run, as you do not follow the signature of AddUndo which takes in a BaseList2D as its second argument; while you are passing in the return value of MergeDocument, a bool. When you just want to wrap your own Undo around a document merging, then you should follow this pattern:

import c4d

def main():
    """
    """
    name = "e:/my_file.c4d"
    flags =  c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS

    doc.StartUndo()
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, doc)
    if not c4d.documents.MergeDocument(doc, name, flags):
        raise IOError("Could not merge documents.")
    doc.EndUndo()
    c4d.EventAdd()


if __name__=='__main__':
    main()

Cheers,
Ferdinand

Hello @ferdinand,
Thank you! His proposal was the best way to solve my problem.
Greetings,
JH23