155 lines
6.1 KiB
Python
155 lines
6.1 KiB
Python
import os
|
|
import bpy
|
|
from .preferences import (AutoExportGltfPreferenceNames)
|
|
from .helpers_scenes import (generate_hollow_scene, clear_hollow_scene)
|
|
from .helpers_collections import (recurLayerCollection)
|
|
from .helpers import (traverse_tree)
|
|
######################################################
|
|
#### Export logic #####
|
|
|
|
|
|
def generate_gltf_export_preferences(addon_prefs):
|
|
# default values
|
|
gltf_export_preferences = dict(
|
|
export_format= 'GLB', #'GLB', 'GLTF_SEPARATE', 'GLTF_EMBEDDED'
|
|
check_existing=False,
|
|
|
|
use_selection=False,
|
|
use_visible=True, # Export visible and hidden objects. See Object/Batch Export to skip.
|
|
use_renderable=False,
|
|
use_active_collection= False,
|
|
use_active_collection_with_nested=False,
|
|
use_active_scene = False,
|
|
|
|
export_texcoords=True,
|
|
export_normals=True,
|
|
# here add draco settings
|
|
export_draco_mesh_compression_enable = False,
|
|
|
|
export_tangents=False,
|
|
#export_materials
|
|
export_colors=True,
|
|
export_attributes=True,
|
|
#use_mesh_edges
|
|
#use_mesh_vertices
|
|
export_cameras=True,
|
|
export_extras=True, # For custom exported properties.
|
|
export_lights=True,
|
|
export_yup=True,
|
|
export_skins=True,
|
|
export_morph=False,
|
|
export_apply=False,
|
|
export_animations=False
|
|
)
|
|
|
|
for key in addon_prefs.__annotations__.keys():
|
|
if str(key) not in AutoExportGltfPreferenceNames:
|
|
#print("overriding setting", key, "value", getattr(addon_prefs,key))
|
|
gltf_export_preferences[key] = getattr(addon_prefs,key)
|
|
|
|
return gltf_export_preferences
|
|
|
|
# find which of the library scenes the given collection stems from
|
|
# TODO: does not seem efficient at all ?
|
|
def get_source_scene(collection_name, library_scenes):
|
|
match = None
|
|
for scene in library_scenes:
|
|
root_collection = scene.collection
|
|
found = False
|
|
for cur_collection in traverse_tree(root_collection):
|
|
if cur_collection.name == collection_name:
|
|
found = True
|
|
break
|
|
if found:
|
|
match = scene
|
|
break
|
|
return match
|
|
|
|
# export collections: all the collections that have an instance in the main scene AND any marked collections, even if they do not have instances
|
|
def export_collections(collections, folder_path, library_scene, addon_prefs, gltf_export_preferences):
|
|
# set active scene to be the library scene (hack for now)
|
|
bpy.context.window.scene = library_scene
|
|
# save current active collection
|
|
active_collection = bpy.context.view_layer.active_layer_collection
|
|
|
|
for collection_name in collections:
|
|
print("exporting collection", collection_name)
|
|
layer_collection = bpy.context.view_layer.layer_collection
|
|
layerColl = recurLayerCollection(layer_collection, collection_name)
|
|
# set active collection to the collection
|
|
bpy.context.view_layer.active_layer_collection = layerColl
|
|
gltf_output_path = os.path.join(folder_path, collection_name)
|
|
|
|
export_settings = { **gltf_export_preferences, 'use_active_scene': True, 'use_active_collection': True, 'use_active_collection_with_nested':True}
|
|
|
|
# if we are using the material library option, do not export materials, use placeholder instead
|
|
export_materials_library = getattr(addon_prefs,"export_materials_library")
|
|
if export_materials_library:
|
|
export_settings['export_materials'] = 'PLACEHOLDER'
|
|
|
|
export_gltf(gltf_output_path, export_settings)
|
|
|
|
# reset active collection to the one we save before
|
|
bpy.context.view_layer.active_layer_collection = active_collection
|
|
|
|
|
|
def export_blueprints_from_collections(collections, library_scene, folder_path, addon_prefs):
|
|
export_output_folder = getattr(addon_prefs,"export_output_folder")
|
|
gltf_export_preferences = generate_gltf_export_preferences(addon_prefs)
|
|
export_blueprints_path = os.path.join(folder_path, export_output_folder, getattr(addon_prefs,"export_blueprints_path")) if getattr(addon_prefs,"export_blueprints_path") != '' else folder_path
|
|
|
|
#print("-----EXPORTING BLUEPRINTS----")
|
|
#print("LIBRARY EXPORT", export_blueprints_path )
|
|
|
|
try:
|
|
export_collections(collections, export_blueprints_path, library_scene, addon_prefs, gltf_export_preferences)
|
|
except Exception as error:
|
|
print("failed to export collections to gltf: ", error)
|
|
# TODO : rethrow
|
|
|
|
|
|
# export all main scenes
|
|
def export_main_scenes(scenes, folder_path, addon_prefs):
|
|
for scene in scenes:
|
|
export_main_scene(scene, folder_path, addon_prefs)
|
|
|
|
def export_main_scene(scene, folder_path, addon_prefs, library_collections):
|
|
export_output_folder = getattr(addon_prefs,"export_output_folder")
|
|
gltf_export_preferences = generate_gltf_export_preferences(addon_prefs)
|
|
|
|
export_blueprints = getattr(addon_prefs,"export_blueprints")
|
|
|
|
if export_blueprints :
|
|
(hollow_scene, object_names) = generate_hollow_scene(scene, library_collections)
|
|
#except Exception:
|
|
# print("failed to create hollow scene")
|
|
|
|
# set active scene to be the given scene
|
|
bpy.context.window.scene = hollow_scene
|
|
|
|
gltf_output_path = os.path.join(folder_path, export_output_folder, scene.name)
|
|
print(" exporting gltf to", gltf_output_path, ".gltf/glb")
|
|
|
|
|
|
export_settings = { **gltf_export_preferences,
|
|
'use_active_scene': True,
|
|
'use_active_collection':True,
|
|
'use_active_collection_with_nested':True,
|
|
'use_visible': False,
|
|
'use_renderable': False,
|
|
'export_apply':True
|
|
}
|
|
export_gltf(gltf_output_path, export_settings)
|
|
|
|
if export_blueprints :
|
|
clear_hollow_scene(hollow_scene, scene, object_names)
|
|
|
|
|
|
#https://docs.blender.org/api/current/bpy.ops.export_scene.html#bpy.ops.export_scene.gltf
|
|
def export_gltf (path, export_settings):
|
|
settings = {**export_settings, "filepath": path}
|
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
bpy.ops.export_scene.gltf(**settings)
|
|
|
|
|