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


Log in to reply