Unsolved Need help fixing export to GLTF script

Hi,

I'm a coding newbie, so I'm often trying to frankenstein code I've found online and then re-write for my purposes.
I have this script which I pieced together which is supposed to take the top-level of the selected meshes and then individually export each as a GLTF.

It works, but not without issue. I noticed it would fail if the object had a Redshift material on it (I didn't need materials, so I added the lines to remove the texture tags). Sometimes C4D will crash when the script runs.
I also noticed that the script will not work (no error or anything) after, separately, doing a regular File->Export->GLTF. Restart C4D and then the script works again.

Hoping someone here can point out any flaws in my script, something that might solve the above issues, or generally ways to do it better.

Thanks!

The code:

import c4d
import os
import string


def export_gltf_for_object(obj, save_dir):
    # Create a new temporary document
    temp_doc = c4d.documents.BaseDocument()

    # Clone the object and insert it into the temporary document
    cloned_obj = obj.GetClone(c4d.COPYFLAGS_NONE, None)
    temp_doc.InsertObject(cloned_obj)

    # Remove material tags from the cloned object
    tags = cloned_obj.GetTags()  # Get a list of all tags on the cloned object
    for tag in tags:
        if isinstance(tag, c4d.TextureTag):  # Check if the tag is a TextureTag (material tag)
            tag.Remove()  # Remove the tag from the object

    # Prepare the file path name
    file_name = obj.GetName() + ".gltf"
    file_path = os.path.join(save_dir, file_name)

    # Retrieve and setup the glTF export plugin.
    objExportId = c4d.FORMAT_GLTFEXPORT
    plug = c4d.plugins.FindPlugin(objExportId, c4d.PLUGINTYPE_SCENESAVER)
    if not plug:
        raise RuntimeError("Failed to retrieve the gltf exporter.")

    data = {}
    if not plug.Message(c4d.MSG_RETRIEVEPRIVATEDATA, data):
        raise RuntimeError("Failed to retrieve private data.")

    # Retrieve and set export settings
    objExport = data.get("imexporter", None)
    if objExport is None:
        raise RuntimeError("Failed to retrieve BaseContainer private data.")

    unit_scale_data = c4d.UnitScaleData()
    unit_scale_data.SetUnitScale(1.0, c4d.DOCUMENT_UNIT_M)  # Adjust as needed
    objExport[c4d.GLTFEXPORTER_UNITSCALE] = unit_scale_data
    objExport[c4d.GLTFEXPORTER_CURRENTFRAME] = True
    objExport[c4d.GLTFEXPORTER_TEXTURES] = False

    # Export the temporary document
    if not c4d.documents.SaveDocument(temp_doc, file_path, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, objExportId):
        raise RuntimeError(f"Failed to save the document for object: {obj.GetName()}")
    
    # Close and delete the temporary document from memory
    c4d.documents.KillDocument(temp_doc)
    
    print(f"Document successfully exported to: {file_path}")

def main():
    # Get a directory to save the exported files
    save_dir = c4d.storage.LoadDialog(title="Select directory for OBJ Exports", type=c4d.FILESELECTTYPE_ANYTHING, flags=c4d.FILESELECT_DIRECTORY)
    if not save_dir:
        return

    active_doc = c4d.documents.GetActiveDocument()
    selected_objects = active_doc.GetActiveObjects(0)  # 0 means no hierarchy, only top-level selected objects

    for obj in selected_objects:
        export_gltf_for_object(obj, save_dir)

if __name__ == '__main__':
    main()

Hello @joel_motion,

Welcome to the Plugin Café forum and the Cinema 4D development community, it is great to have you with us!

Getting Started

Before creating your next postings, we would recommend making yourself accustomed with our Forum and Support Guidelines, as they line out details about the Maxon SDK Group support procedures. Of special importance are:

About your First Question

Support for redshift materials on gltf export first appeared with the 2023.2 release. That version also included numerous gltf exporter stability improvements.

Please note, that debugging the code is out of scope in this forum. You are very welcome to ask specific questions with well-defined scope.

In general your code seems reasonable. The approach with cloning objects onto a new document is the one I would suggest anyways. However, one should be careful with the dependencies that objects in the subtree might loose during cloning. AliasTrans helps to overcome such side effects to some extent.

Cheers,
Ilia

MAXON SDK Specialist
developers.maxon.net

This post is deleted!