Unsolved Export fbx of only selected objects

I'm trying to write a simple script to export an fbx of the selected objects.

import c4d
import os

def main():
    # Get the currently open document
    doc = c4d.documents.GetActiveDocument()
    if doc is None:
        return

    # Get the selected objects
    selected_objects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)

    if not selected_objects:
        return

    # Get the file path of the currently open document
    filepath = doc.GetDocumentPath()
    if not filepath:
        return

    # Get the name of the currently open document
    docname = os.path.splitext(doc.GetDocumentName())[0]

    # Get the name of the first selected object
    first_object_name = selected_objects[0].GetName()
    

    # Create the FBX file path and name
    fbx_filepath = os.path.join(filepath, docname + "_" + first_object_name + ".fbx")
    
    #make fbx exporter only export selected object
    c4d.FBXEXPORT_SELECTION_ONLY = True

    # Export the selected objects as an FBX file
    c4d.documents.SaveDocument(doc, fbx_filepath, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, 1026370)

if __name__ == '__main__':
    main()

But it keeps exporting the whole scene.
Sorry im a total noob at this.

all cards on the table, i'm using chat gpt to write this script. :)) It was very helpful at modifying existing scripts, but seems to be failing here.

after some reading i found some info about loading a plugin 1026370. so i got it to write a new script:

import os
import c4d
from c4d import documents, gui

def main():
    # Get the active document and the current path
    doc = documents.GetActiveDocument()
    doc_path = doc.GetDocumentPath()
    doc_name = doc.GetDocumentName()

    # Get the selected objects
    selected_objects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)

    # Check if there are any selected objects
    if not selected_objects:
        gui.MessageDialog('No objects selected. Please select at least one object and try again.')
        return

    # Set the FBX export path and name
    first_obj_name = selected_objects[0].GetName()
    fbx_name = '{}_{}.fbx'.format(doc_name, first_obj_name)
    fbx_path = os.path.join(doc_path, fbx_name)

    # Initialize FBX export settings
    fbx_export_settings = c4d.BaseContainer()
    fbx_export_settings.SetBool(c4d.FBXEXPORT_ASCII, True)
    fbx_export_settings.SetBool(c4d.FBXEXPORT_EMBED_TEXTURES, False)
    fbx_export_settings.SetBool(c4d.FBXEXPORT_SELECTION_ONLY, True)

    # Get the FBX exporter plugin ID
    fbx_exporter_id = c4d.FBX_EXPORTVERSION_7_5_0
    if fbx_exporter_id == 0:
        fbx_exporter_id = 1026370  # Use the plugin ID directly for Cinema 4D 2023.1

    # Export the selected objects to an FBX file
    result = documents.SaveDocument(doc, fbx_path, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, 
                                    fbx_exporter_id, fbx_export_settings)

    if result:
        gui.MessageDialog('FBX export successful: {}'.format(fbx_path))
    else:
        gui.MessageDialog('FBX export failed. Please check the file path and try again.')

if __name__=='__main__':
    main()

but now i get an error: TypeError: function takes at most 4 arguments (5 given)

Even though my answer might not be as perfect as the C4D teams I 'll jump in here.

You are passing 5 arguments (noob speek 5 variables in the brakets ) to a function that only takes 4 -> SaveDocument ... as you can see here it needs only 4 the fbx settings are stored they re not passed as I understand.

Noob Gotcha: You can combine flags as a single argument with the pipe | symbol

# this is one argument
flags=c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST | c4d.SAVEDOCUMENTFLAGS_EXPORTDIALOG

as a beginner i find it helpful to write the function with its parameters

# i did not test this ... 
c4d.documents.SaveDocument(doc=doc, name=fbx_path, saveflags=c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, 
                           format=c4d.FORMAT_FBX_EXPORT)

ChatGPT gives better results if you prompt it to give you a single python function. With C4D. specific stuff it often cobbles 10 year old code with new sdk stuff.... resulting in a weird code

hope this helps ----
cheers mogh

@mogh

Thanks man, yeah im starting to catch on that it's using old code in places..

I removed the 4th parameter, but now it's giving me the error message dialogue 😞 ( something about the filepath failure.

i tried getting the filepath building from the first script, because that one actually worked, just refuses to export only selected object. but the 2nd script did not like that either..

i feel so close! yet so far away 🙂

You probably still using the PuginID (chatGPT gibberisch) look at the above mentioned savedoc() and compare it to yours .... I testet it just now and it works for me ...

Hello @Aleksey ,

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

The problem with ChatGPT, as amazing as its principal abilities are, is that it seems to struggle with how im- and exporters work in our API. And in true ChatGPT fashion it then starts making up things which simply do not exist, as for example c4d.FBXEXPORT_SELECTION_ONLY = True or the fifth SaveDocument argument.

The problem which arises here for us is that this whole workflow, not writing code manually and serving here that automatically generated for others to fix, is in essence a violation our guidelines as lined out in Forum Guidelines: Scope of Support:

  • If necessary, we will provide code examples, but we will not provide full solutions or design applications.
  • "It doesn't work" is not a support request and ultimately, we will not debug code, but instead provide answers to specific problems.

Or in short, the rule of every coding-community in the world also does apply here: "we will not do your homework for you". There are of course nuances here, and ChatGPT differs at least a little from straight up asking for a solution. But in the end, we cannot fix the code for everyone who is able to use ChatGPT but does not know our APIs or how to use Python/C++ in general. We would be simply overwhelmed by this, our support has always the goal to help users being able to help themselves in the future by understanding something fundamentally.

We had a brief talk about this subject this morning and haven't come to a full conclusion on how we will deal with this in the future. To be clear here, the fault does not lie with you, @Aleksey, as nothing explicitly forbids this being done at the moment. But we might restrict support requests which are based on code that clearly has been automatically generated. We can of course see the advantages in allowing this for the community, having an easy entry point for them. But at the same time, the sheer amount of support requests this could entail is a problem.


The Python example export_obj_r13.py demonstrates how to modify the settings of an im- or exporter plugin at the case of the OBJ exporter. I also provided an example specific to this case below.

Cheers,
Ferdinand

Code:

"""Provides an example for setting the parameters of an im- or exporter plugin.

See also:
    https://github.com/PluginCafe/cinema4d_py_sdk_extended/blob/master/scripts/
    03_application_development/files_media/export_obj_r13.py
"""

import c4d
import os

doc: c4d.documents.BaseDocument # The active document.

def main():
    """
    """
    # Check that there is document path to infer from the active document.
    if doc.GetDocumentPath() == "":
        c4d.gui.MessageDialog("Cannot infer save location from unsaved document.")
        return

    # Get the selected objects
    selectedObjects: list[c4d.BaseObject] = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    if not selectedObjects:
        c4d.gui.MessageDialog("No objects selected. Please select at least one object and try again.")
        return
    
    # Get the FBX exporter plugin.
    plugin: c4d.plugins.BasePlugin = c4d.plugins.FindPlugin(
        c4d.FORMAT_FBX_EXPORT, c4d.PLUGINTYPE_SCENESAVER)
    if not plugin:
        raise RuntimeError("Could not find FBX exporter plugin.")

    # Get the internal data so that we write the setting we want to write, handling the settings
    # of im- and exporter plugins is a bit fiddly as the plugin node itself does not hold these
    # parameters.
    privateData: dict = {}
    if not plugin.Message(c4d.MSG_RETRIEVEPRIVATEDATA, privateData):
        raise RuntimeError("Failed to retrieve private FBX exporter plugin data.")

    settings: c4d.BaseList2D = privateData.get("imexporter", None)
    if settings is None:
        raise RuntimeError("Failed to retrieve settings node for FBX exporter plugin.")

    # The is just normal parameter access.
    settings[c4d.FBXEXPORT_SELECTION_ONLY] = True

    # Now we can invoke the exporter with the settings we have defined.
    documentName: str = f"{doc.GetDocumentName()}_{selectedObjects[0].GetName()}"
    filePath: str = os.path.join(doc.GetDocumentPath(), documentName)
    res: bool = c4d.documents.SaveDocument(
        doc, filePath, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, c4d.FORMAT_FBX_EXPORT)
    
    if res:
        c4d.gui.MessageDialog(f"FBX export successful: {filePath}")
    else:
        c4d.gui.MessageDialog("FBX export failed. Please check the file path and try again.")

if __name__=='__main__':
    main()

MAXON SDK Specialist
developers.maxon.net

@ferdinand THanks! I got it to work!

I totally understand the issues with providing support for chatGPT, but don't be so hard on it, adding "c4d.FBXEXPORT_SELECTION_ONLY = True" was the work of my hands 🙂 So that wasn't it's mistake.

I grabbed that command from here: https://developers.maxon.net/docs/Cinema4DPythonSDK/html/classic_resource/file_base/ffbxexport.html?highlight=fbx export

Currently i find chat GPT is super handy for commenting existing scripts and figuring out how they work.

So i am actually learning, not just pasting chat gpt code 🙂

Hello @Aleksey,

I am glad to hear that you found your solution. And as lined out above, we are of course aware that ChatGPT is also an excellent learning tool, and it is therefore in our interest to allow it. But there is also the other side to it, and that is why we are a bit undecided on how we will deal with it in the future.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net