Solved Commiting Xrefs to the scene

Hey!

Im looking to make a simple script that commits all xrefs to the scene before sending it off to render. I have this working so far (it's still WIP) and is almost doing what i need - I just need to figure out how to get the materials to commit to the file too.

Im basically trying to emulate what happens if you select and xref and hit 'c'

Any / all info much appreciated!

Cheers,

C

import c4d
from c4d import gui, utils
#Welcome to the world of Python


def GetNextObj(op):
    if op==None: return None
    if op.GetDown():
        return op.GetDown()
    while not op.GetNext() and op.GetUp():
        op = op.GetUp()
    return op.GetNext()

# Main function
def main():
    obj = doc.GetFirstObject()

    allobjs = []
    allXrefs = []
    xRef = 1025766

    # Gets all objs and stores them in a list
    while GetNextObj(obj):
        allobjs.append(GetNextObj(obj))
        obj = GetNextObj(obj)
    
    print len(allobjs)

    for i in allobjs:
        if i.GetType() == 1025766:
            allXrefs.append(i)

    res = utils.SendModelingCommand(command=c4d.MCOMMAND_MAKEEDITABLE,

                                    list=allXrefs,

                                    mode=c4d.MODELINGCOMMANDMODE_ALL,

                                    bc=c4d.BaseContainer(),

                                    doc=doc)
                                
    doc.StartUndo() 
                
    for i in res:
        doc.InsertObject(i)
    

    #for i in res:
        #doc.AddUndo(c4d.UNDOTYPE_NEW,i)
    
    #for i in allXrefs:
        #doc.AddUndo(c4d.UNDOTYPE_DELETE,i)
    
    for i in allXrefs:
        i.Remove()
    
    doc.EndUndo()

    c4d.EventAdd()

No worries - i solved it with a call command in the end. It would be good to know how to commit xref materials to the scene as well though.

hello,
the xref will import the material unless it's on Generator mode.

You can maybe juste merge de target document with your current document. This work with a simple scene of course but can go really more complicated.

def main():
    if op is None: 
        raise ValueError("you have to select at least one object")
    
    if not op.IsInstanceOf(c4d.Oxref):
        raise ValueError("selected object must be a xref")
    
    # Starts Undo
    doc.StartUndo()
    
    # if the xref is in generator mode, we need to import the material from the target document.
    if op[c4d.ID_CA_XREF_GENERATOR]:
        
        targetDoc = op[c4d.ID_CA_XREF_FILE]
        c4d.documents.MergeDocument(doc, targetDoc, c4d.SCENEFILTER_MATERIALS | c4d.SCENEFILTER_OBJECTS, None)
        
    else:
        result = c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_CURRENTSTATETOOBJECT,
                                list = [op]
                                , doc=doc)
        
        if result:
            doc.InsertObject(result[0])
            doc.AddUndo(c4d.UNDOTYPE_NEW, result[0])
        else:
            raise ValueError("couldn't retrieves the CSTO of the xref")
    
    #remove the existing xref
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)
    op.Remove()
    
            
    doc.EndUndo()    
        
    c4d.EventAdd()

Cheers,
Manuel

MAXON SDK Specialist

MAXON Registered Developer