SOLVED 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?

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

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 [email protected] ?

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.