glTF exporter: add option to export textures into a folder
This commit is contained in:
parent
a659ebbd5d
commit
60a11a0fc4
|
@ -15,7 +15,7 @@
|
|||
bl_info = {
|
||||
'name': 'glTF 2.0 format',
|
||||
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
|
||||
"version": (1, 1, 26),
|
||||
"version": (1, 1, 27),
|
||||
'blender': (2, 81, 6),
|
||||
'location': 'File > Import-Export',
|
||||
'description': 'Import-Export as glTF 2.0',
|
||||
|
@ -127,6 +127,12 @@ class ExportGLTF2_Base:
|
|||
default='NAME'
|
||||
)
|
||||
|
||||
export_texture_dir: StringProperty(
|
||||
name='Textures',
|
||||
description='Folder to place texture files in. Relative to the .gltf file',
|
||||
default='',
|
||||
)
|
||||
|
||||
export_texcoords: BoolProperty(
|
||||
name='UVs',
|
||||
description='Export UVs (texture coordinates) with meshes',
|
||||
|
@ -347,7 +353,8 @@ class ExportGLTF2_Base:
|
|||
del context.scene[self.scene_key]
|
||||
|
||||
import sys
|
||||
for addon_name in bpy.context.preferences.addons.keys():
|
||||
preferences = bpy.context.preferences
|
||||
for addon_name in preferences.addons.keys():
|
||||
try:
|
||||
if hasattr(sys.modules[addon_name], 'glTF2ExportUserExtension'):
|
||||
extension_panel_unregister_functors.append(sys.modules[addon_name].register_panel())
|
||||
|
@ -385,6 +392,10 @@ class ExportGLTF2_Base:
|
|||
|
||||
export_settings['gltf_filepath'] = bpy.path.ensure_ext(self.filepath, self.filename_ext)
|
||||
export_settings['gltf_filedirectory'] = os.path.dirname(export_settings['gltf_filepath']) + '/'
|
||||
export_settings['gltf_texturedirectory'] = os.path.join(
|
||||
export_settings['gltf_filedirectory'],
|
||||
self.export_texture_dir,
|
||||
)
|
||||
|
||||
export_settings['gltf_format'] = self.export_format
|
||||
export_settings['gltf_image_format'] = self.export_image_format
|
||||
|
@ -452,7 +463,8 @@ class ExportGLTF2_Base:
|
|||
user_extensions = []
|
||||
|
||||
import sys
|
||||
for addon_name in bpy.context.preferences.addons.keys():
|
||||
preferences = bpy.context.preferences
|
||||
for addon_name in preferences.addons.keys():
|
||||
if hasattr(sys.modules[addon_name], 'glTF2ExportUserExtension'):
|
||||
extension_ctor = sys.modules[addon_name].glTF2ExportUserExtension
|
||||
user_extensions.append(extension_ctor())
|
||||
|
@ -492,6 +504,8 @@ class GLTF_PT_export_main(bpy.types.Panel):
|
|||
operator = sfile.active_operator
|
||||
|
||||
layout.prop(operator, 'export_format')
|
||||
if operator.export_format == 'GLTF_SEPARATE':
|
||||
layout.prop(operator, 'export_texture_dir', icon='FILE_FOLDER')
|
||||
layout.prop(operator, 'export_copyright')
|
||||
layout.prop(operator, 'will_save_settings')
|
||||
|
||||
|
|
|
@ -49,21 +49,15 @@ def save(context, export_settings):
|
|||
|
||||
|
||||
def __export(export_settings):
|
||||
exporter = GlTF2Exporter(__get_copyright(export_settings))
|
||||
exporter = GlTF2Exporter(export_settings)
|
||||
__gather_gltf(exporter, export_settings)
|
||||
buffer = __create_buffer(exporter, export_settings)
|
||||
exporter.finalize_images(export_settings[gltf2_blender_export_keys.FILE_DIRECTORY])
|
||||
exporter.finalize_images()
|
||||
json = __fix_json(exporter.glTF.to_dict())
|
||||
|
||||
return json, buffer
|
||||
|
||||
|
||||
def __get_copyright(export_settings):
|
||||
if export_settings[gltf2_blender_export_keys.COPYRIGHT]:
|
||||
return export_settings[gltf2_blender_export_keys.COPYRIGHT]
|
||||
return None
|
||||
|
||||
|
||||
def __gather_gltf(exporter, export_settings):
|
||||
active_scene_idx, scenes, animations = gltf2_blender_gather.gather_gltf2(export_settings)
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ JOINT_CACHE = 'gltf_joint_cache'
|
|||
COPYRIGHT = 'gltf_copyright'
|
||||
FORMAT = 'gltf_format'
|
||||
FILE_DIRECTORY = 'gltf_filedirectory'
|
||||
TEXTURE_DIRECTORY = 'gltf_texturedirectory'
|
||||
BINARY_FILENAME = 'gltf_binaryfilename'
|
||||
YUP = 'gltf_yup'
|
||||
MORPH = 'gltf_morph'
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import re
|
||||
import os
|
||||
import urllib.parse
|
||||
from typing import List
|
||||
|
||||
from ... import get_version_string
|
||||
|
@ -20,6 +22,7 @@ from io_scene_gltf2.io.com import gltf2_io_extensions
|
|||
from io_scene_gltf2.io.exp import gltf2_io_binary_data
|
||||
from io_scene_gltf2.io.exp import gltf2_io_buffer
|
||||
from io_scene_gltf2.io.exp import gltf2_io_image_data
|
||||
from io_scene_gltf2.blender.exp import gltf2_blender_export_keys
|
||||
|
||||
|
||||
class GlTF2Exporter:
|
||||
|
@ -29,9 +32,11 @@ class GlTF2Exporter:
|
|||
Any child properties are replaced with references where necessary
|
||||
"""
|
||||
|
||||
def __init__(self, copyright=None):
|
||||
def __init__(self, export_settings):
|
||||
self.export_settings = export_settings
|
||||
self.__finalized = False
|
||||
|
||||
copyright = export_settings[gltf2_blender_export_keys.COPYRIGHT] or None
|
||||
asset = gltf2_io.Asset(
|
||||
copyright=copyright,
|
||||
extensions=None,
|
||||
|
@ -143,14 +148,15 @@ class GlTF2Exporter:
|
|||
self.__gltf.extensions_required.append('KHR_draco_mesh_compression')
|
||||
self.__gltf.extensions_used.append('KHR_draco_mesh_compression')
|
||||
|
||||
def finalize_images(self, output_path):
|
||||
def finalize_images(self):
|
||||
"""
|
||||
Write all images.
|
||||
|
||||
Due to a current limitation the output_path must be the same as that of the glTF file
|
||||
:param output_path:
|
||||
:return:
|
||||
"""
|
||||
output_path = self.export_settings[gltf2_blender_export_keys.TEXTURE_DIRECTORY]
|
||||
|
||||
if self.__images:
|
||||
os.makedirs(output_path, exist_ok=True)
|
||||
|
||||
for name, image in self.__images.items():
|
||||
dst_path = output_path + "/" + name + image.file_extension
|
||||
with open(dst_path, 'wb') as f:
|
||||
|
@ -222,12 +228,17 @@ class GlTF2Exporter:
|
|||
name += "-" + str(count)
|
||||
|
||||
count += 1
|
||||
# TODO: we need to know the image url at this point already --> maybe add all options to the constructor of the
|
||||
# exporter
|
||||
# TODO: allow embedding of images (base64)
|
||||
|
||||
self.__images[name] = image
|
||||
return name + image.file_extension
|
||||
|
||||
texture_dir = self.export_settings[gltf2_blender_export_keys.TEXTURE_DIRECTORY]
|
||||
abs_path = os.path.join(texture_dir, name + image.file_extension)
|
||||
rel_path = os.path.relpath(
|
||||
abs_path,
|
||||
start=self.export_settings[gltf2_blender_export_keys.FILE_DIRECTORY],
|
||||
)
|
||||
return _path_to_uri(rel_path)
|
||||
|
||||
@classmethod
|
||||
def __get_key_path(cls, d: dict, keypath: List[str], default):
|
||||
|
@ -313,3 +324,8 @@ class GlTF2Exporter:
|
|||
# do nothing for any type that does not match a glTF schema (primitives)
|
||||
return node
|
||||
|
||||
def _path_to_uri(path):
|
||||
path = os.path.normpath(path)
|
||||
path = path.replace(os.sep, '/')
|
||||
return urllib.parse.quote(path)
|
||||
|
||||
|
|
Loading…
Reference in New Issue