[Bf-extensions-cvs] [60a11a0f] master: glTF exporter: add option to export textures into a folder

Julien Duroure noreply at git.blender.org
Sun Dec 29 13:13:42 CET 2019


Commit: 60a11a0fc4426f01e87be0e019c5d909889e511e
Author: Julien Duroure
Date:   Sun Dec 29 13:05:31 2019 +0100
Branches: master
https://developer.blender.org/rBA60a11a0fc4426f01e87be0e019c5d909889e511e

glTF exporter: add option to export textures into a folder

===================================================================

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_export.py
M	io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py

===================================================================

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 40beaca1..78141088 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -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')
 
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_export.py b/io_scene_gltf2/blender/exp/gltf2_blender_export.py
index 06af24cc..94babf78 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_export.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_export.py
@@ -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)
 
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py b/io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py
index a8daa6b4..8813337b 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py
@@ -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'
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py b/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
index fe50b407..2c44a018 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
@@ -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)
+



More information about the Bf-extensions-cvs mailing list