Can't find any api documentation on adding a Custom Collection Exporter

There is no api documentation on adding your own custom Collection Exporter to the menu dropdown for collections.

1 Like

After searching in Blender’s source code and online docs

I think you need to implement a file handler

https://docs.blender.org/api/current/bpy.types.FileHandler.html#bpy.types.FileHandler.bl_export_operator

and define bl_export_operator (the online example shows bl_import_operator
https://docs.blender.org/api/current/bpy.types.FileHandler.html#bpy.types.FileHandler.bl_export_operator

I did that, but it’s still not showing up.

class IO_FH_bml(bpy.types.FileHandler):
bl_idname = “IO_FH_bml”
bl_label = “BML”
bl_export_operator = ExportBML.bl_idname
bl_file_extensions = “.bml”

@classmethod
def poll_drop(cls, context):
    return poll_file_object_drop(context)
1 Like

bl_export_operator = ExportBML.bl_idname

is kind of wrong,

it needs to be the name of a bpy.types.Operator

not File Handler

you have to register both an operator and file handler

please check the import operator with file handler example and adapt it to an export operator
https://docs.blender.org/api/current/bpy.types.FileHandler.html#filehandler-bpy-struct

Sorry for the confusion, our docs could indeed be better. I’ll do that this week. In the meantime I’ll attach a working example for your reference.

Essentially you do 3 things:

  • Create a FileHandler and ensure the bl_export_operator is set and the handler is registered
  • Ensure your Operator class has a special StringProperty called collection
  • Implement the Operator draw function to layout only the properties necessary

FBX commit for reference: FBX: Enable the Collection exporter feature · 4f815e960a - blender-addons - Blender Projects

import bpy

from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator

class ExportBML(Operator, ExportHelper):
    """This appears in the tooltip of the operator and in the generated docs"""
    bl_idname = "export_test.some_data"  # important since its how bpy.ops.import_test.some_data is constructed
    bl_label = "Export Some Data"

    # ExportHelper mix-in class uses this.
    filename_ext = ".bml"
    filter_glob: StringProperty(default="*.bml", options={'HIDDEN'}, maxlen=255)

    # Standard assortment of operator properties
    use_setting: BoolProperty(
        name="Example Boolean",
        description="Example Tooltip",
        default=True,
    )

    type: EnumProperty(
        name="Example Enum",
        description="Choose between two items",
        items=(
            ('OPT_A', "First Option", "Description one"),
            ('OPT_B', "Second Option", "Description two"),
        ),
        default='OPT_A',
    )

    # Special property that Collection export will use. It is the responsibility
    # of the addon here to properly iterate over the collection to accumulate all
    # objects
    collection: StringProperty(
        name="Source Collection",
        description="Export only objects from this collection (and its children)",
        default="",
    )

    def draw(self, context):
        layout = self.layout
        layout.use_property_split = True
        layout.use_property_decorate = False  # No animation.    

        col = layout.column()
        col.prop(self, "use_setting")
        col.prop(self, "type")

    def execute(self, context):
        print("Do actual work...")
        return {'FINISHED'}


class IO_FH_bml(bpy.types.FileHandler):
    bl_idname = "IO_FH_bml"
    bl_label = "BML"
    bl_export_operator = ExportBML.bl_idname
    bl_file_extensions = ".bml"
    

# Register and add to the "file selector" menu (required to use F3 search "Text Export Operator" for quick access).
def register():
    bpy.utils.register_class(ExportBML)
    bpy.utils.register_class(IO_FH_bml)

def unregister():
    bpy.utils.unregister_class(IO_FH_bml)
    bpy.utils.unregister_class(ExportBML)

if __name__ == "__main__":
    register()
2 Likes

Thanks everyone. I finally figured out my issue.

The auto_load.py didn’t include FileHandler in the base types, which meant that my file handler class was not registered.

After I added FileHandler to the function get_register_base_types() it worked.