Exporting Polygonized scene



  • I have a script that exports a sequence of OBJ files out of an animated Cinema 4D scene. It works perfectly.
    I would like to be able to do the same, but export as a sequence of C4D files.
    What I need is to export a sequence of frames (the scene has animation, of course), in C4D format, but with everything polygonized.
    I'm using:

    ...
                doc.SetTime(curr_time)
                # Force the redraw of the document
                doc.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_NONE)
                c4d.EventAdd(c4d.EVENT_FORCEREDRAW)
                c4d.DrawViews(c4d.DRAWFLAGS_FORCEFULLREDRAW)
    
                bufferedNumber = str(frame_num)
                frame_num=frame_num+1
    
                # Export the C4D file
                file_name = os.path.join(file_path,obj_name+bufferedNumber+".c4d")
    
                poly_doc=doc.Polygonize(keepanimation = False)
    
                if poly_doc != None: c4d.documents.SaveDocument(poly_doc,file_name,c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST | c4d.SAVEDOCUMENTFLAGS_SAVECACHES,c4d.FORMAT_C4DEXPORT)
    
    

    But all the saved files are the same and I wanted each file to export as different frame, already polygonized.
    Is this possible?



  • hello,

    This is not really clear to us :
    If your code is working for obj, it should work with c4d.
    We are not sure if the problem is in your code or in your scene.
    I've created that script, it's working with a simple cube animated with keyframes.

    Just a remark about your code, you should use is not None

    if poly_doc is not None:
         ..... dosomething
    
    import c4d
    from c4d import gui
    import os
    # Welcome to the world of Python
    
    # Main function
    def main():
        # Retrieves the file name and path
        file_path = doc.GetDocumentPath()
        file_oriname = doc.GetDocumentName()[:-3] #remove .c4d
    
        for i in xrange(10):
            # Update the document's time
            doc.SetTime(c4d.BaseTime(i, doc.GetFps()))
    
            # Updates timeline
            c4d.GeSyncMessage(c4d.EVMSG_TIMECHANGED)
            # Sometimes you must execute this twice to be sure cache is built.
            doc.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_NONE)
            doc.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_NONE)
    
            currentFrame = doc.GetTime().GetFrame(doc.GetFps())
            # Export the C4D file
            file_name = os.path.join(file_path,file_oriname + str(currentFrame) + ".c4d")
    
            poly_doc=doc.Polygonize(keepanimation = False)
    
            if poly_doc != None:
                c4d.documents.SaveDocument(poly_doc,file_name,c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST | c4d.SAVEDOCUMENTFLAGS_SAVECACHES,c4d.FORMAT_C4DEXPORT)
    
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    Cheers,
    Manuel



  • I'm trying to export a Dynamics MoGraph animation, with a Voronoi Fracture object.
    If I export as OBJ, it works fine.
    If I export as C4D, all the saved files are the same, and have no animation.



  • hi,

    it seem to have a bug with Polygonize, we are investigating at the moment.
    Some exporter are using this function other aren't. .obj is not that's probably why it's working with obj.

    The Polygonize function is just a "current state to object" for each object in the scene. You can build your own Polygonize function.

    I'll be back when i have more information

    Cheers,
    Manuel



  • hello,

    Something like this maybe. I needed to create my own "insertLast" function because the GeListHead was not alive in the new document.
    But i don't build my scene with dynamics, could you send us your scene at sdk_support@maxon.net ?

    sorry for the small amount of comment.

    import c4d
    from c4d import gui
    import os
    # Welcome to the world of Python
    def GetLast(doc):
        # retrieves the last element of the document
        child = doc.GetFirstObject()
        if child is None:
            return None
        while child:
            if child.GetNext() is None:
                return child
            child = child.GetNext()
    
    def InsertLast(doc, op):
        # Insert object after the last object in the scene.
        last = GetLast(doc)
        
        if last is None:
            # that mean this is the first element added in the scene
            doc.InsertObject(op)
        else:
            op.InsertAfter(last)
    
    
    def CSTO(op, keepAnimation = False ):
        # Current state to object.
        # the Keep animation will be set in the basecontainer for the command
        doc = op.GetDocument()
        # send the modeling command
        bc = c4d.BaseContainer()
        
        bc.SetBool(c4d.MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION, keepAnimation)
        res = c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_CURRENTSTATETOOBJECT,
                                    list = [op],
                                    mode = c4d.MODELINGCOMMANDMODE_ALL,
                                    bc = bc,
                                    doc = doc)
    
        # Cheks if the command didn't failed
        if res is False:
            raise TypeError("return value of CSTO is not valie")
    
        # Returns the first object of the list.
        return res[0]
    
    def GetNextObject(doc):
        # get he next object in the scene, only the first level of hierarchy is used.
        op = doc.GetFirstObject()
        while op:
            yield op
            op=op.GetNext()
    
    def MyPolygonize(doc, keepAnimation = False):
        # For each first level element, call a CSTO and store the result in a new document
        
        dst = c4d.documents.BaseDocument()
        if dst is None:
            raise ValueError("can't create a new document")
    
        for op in GetNextObject(doc):
            res = CSTO(op, keepAnimation)
            InsertLast(dst, res)
    
        return dst
    
    
    def main():
        file_path = doc.GetDocumentPath()
        file_oriname = doc.GetDocumentName()[:-3] #remove .c4d
        dst = None
    
        for i in xrange(10):
            # Update the document's time
            doc.SetTime(c4d.BaseTime(i, doc.GetFps()))
    
            # Updates timeline
            c4d.GeSyncMessage(c4d.EVMSG_TIMECHANGED)
            # Sometimes you must execute this twice to be sure cache is built.
            # Using the flag BUILDFLAGS_INTERNALRENDERER will allow to have the voronoi fracture cache to be calculated 
            doc.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_INTERNALRENDERER)
            
    
            currentFrame = doc.GetTime().GetFrame(doc.GetFps())
            # Export the C4D file
            file_name = os.path.join(file_path,file_oriname + str(currentFrame) + ".c4d")
    
            dst = MyPolygonize(doc, False)
    
    
            if dst is not None:
                c4d.documents.SaveDocument(dst,file_name,c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST | c4d.SAVEDOCUMENTFLAGS_SAVECACHES,c4d.FORMAT_C4DEXPORT)
    
    
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    Cheers,
    Manuel



  • Thank you very much, Manuel.
    I will send the scene to the e-mail you provided.



  • hi,

    of course my example doesn't take care of material applied to the object, you need a bit of extra work for that. But shouldn't be too hard.
    thanks for the scene :)

    Cheers,
    Manuel



  • You're welcome, Manuel.

    Actually, I usually prepare all the textures and mapping to be in UVW mapping, when texturing is required.
    But, mainly, what I need is exporting geometry that is animated.