[Bf-extensions-cvs] [0a26f6cc] master: glTF exporter: Draco compression

Julien Duroure noreply at git.blender.org
Tue Apr 2 22:15:56 CEST 2019


Commit: 0a26f6cce99ce064c48a75c2df7533b2b3156d42
Author: Julien Duroure
Date:   Tue Apr 2 22:13:43 2019 +0200
Branches: master
https://developer.blender.org/rBA0a26f6cce99ce064c48a75c2df7533b2b3156d42

glTF exporter: Draco compression

Note that blender must use this patch to use Draco compression: https://developer.blender.org/D4501
Currenlty, this patch is not merged yet into master

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

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_export.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
A	io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py

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

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 7318487e..8c4d8db4 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -14,7 +14,7 @@
 
 bl_info = {
     'name': 'glTF 2.0 format',
-    'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen',
+    'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein',
     "version": (0, 0, 1),
     'blender': (2, 80, 0),
     'location': 'File > Import-Export',
@@ -26,6 +26,7 @@ bl_info = {
     'category': 'Import-Export',
 }
 
+
 #
 # Script reloading (if the user calls 'Reload Scripts' from Blender)
 #
@@ -33,6 +34,7 @@ bl_info = {
 def reload_package(module_dict_main):
     import importlib
     from pathlib import Path
+
     def reload_package_recursive(current_dir, module_dict):
         for path in current_dir.iterdir():
             if "__init__" in str(path) or path.stem not in module_dict:
@@ -56,6 +58,7 @@ from bpy.props import (StringProperty,
                        IntProperty)
 from bpy.types import Operator
 from bpy_extras.io_utils import ImportHelper, ExportHelper
+from io_scene_gltf2.io.exp import gltf2_io_draco_compression_extension
 
 
 #
@@ -64,9 +67,11 @@ from bpy_extras.io_utils import ImportHelper, ExportHelper
 
 
 class ExportGLTF2_Base:
-
     # TODO: refactor to avoid boilerplate
 
+    def __init__(self):
+        self.is_draco_available = gltf2_io_draco_compression_extension.dll_exists()
+
     bl_options = {'UNDO', 'PRESET'}
 
     export_format: EnumProperty(
@@ -114,6 +119,44 @@ class ExportGLTF2_Base:
         default=True
     )
 
+    export_draco_mesh_compression_enable: BoolProperty(
+        name='Draco mesh compression',
+        description='Compress mesh using Draco',
+        default=False
+    )
+
+    export_draco_mesh_compression_level: IntProperty(
+        name='Compression level',
+        description='Compression level (0 = most speed, 6 = most compression, higher values currently not supported)',
+        default=6,
+        min=0,
+        max=6
+    )
+
+    export_draco_position_quantization: IntProperty(
+        name='Position quantization bits',
+        description='Quantization bits for position values (0 = no quantization)',
+        default=14,
+        min=0,
+        max=30
+    )
+
+    export_draco_normal_quantization: IntProperty(
+        name='Normal quantization bits',
+        description='Quantization bits for normal values (0 = no quantization)',
+        default=10,
+        min=0,
+        max=30
+    )
+
+    export_draco_texcoord_quantization: IntProperty(
+        name='Texcoord quantization bits',
+        description='Quantization bits for texture coordinate values (0 = no quantization)',
+        default=12,
+        min=0,
+        max=30
+    )
+
     export_tangents: BoolProperty(
         name='Tangents',
         description='Export vertex tangents with meshes',
@@ -309,11 +352,21 @@ class ExportGLTF2_Base:
         export_settings['gltf_texcoords'] = self.export_texcoords
         export_settings['gltf_normals'] = self.export_normals
         export_settings['gltf_tangents'] = self.export_tangents and self.export_normals
+
+        if self.is_draco_available:
+            export_settings['gltf_draco_mesh_compression'] = self.export_draco_mesh_compression_enable
+            export_settings['gltf_draco_mesh_compression_level'] = self.export_draco_mesh_compression_level
+            export_settings['gltf_draco_position_quantization'] = self.export_draco_position_quantization
+            export_settings['gltf_draco_normal_quantization'] = self.export_draco_normal_quantization
+            export_settings['gltf_draco_texcoord_quantization'] = self.export_draco_texcoord_quantization
+        else:
+            export_settings['gltf_draco_mesh_compression'] = False
+
         export_settings['gltf_materials'] = self.export_materials
         export_settings['gltf_colors'] = self.export_colors
         export_settings['gltf_cameras'] = self.export_cameras
         export_settings['gltf_selected'] = self.export_selected
-        export_settings['gltf_layers'] = True #self.export_layers
+        export_settings['gltf_layers'] = True  # self.export_layers
         export_settings['gltf_extras'] = self.export_extras
         export_settings['gltf_yup'] = self.export_yup
         export_settings['gltf_apply'] = self.export_apply
@@ -385,6 +438,17 @@ class ExportGLTF2_Base:
         col.prop(self, 'export_colors')
         col.prop(self, 'export_materials')
 
+        # Add Draco compression option only if the DLL could be found.
+        if self.is_draco_available:
+            col.prop(self, 'export_draco_mesh_compression_enable')
+
+            # Display options when Draco compression is enabled.
+            if self.export_draco_mesh_compression_enable:
+                col.prop(self, 'export_draco_mesh_compression_level')
+                col.prop(self, 'export_draco_position_quantization')
+                col.prop(self, 'export_draco_normal_quantization')
+                col.prop(self, 'export_draco_texcoord_quantization')
+
     def draw_object_settings(self):
         col = self.layout.box().column()
         col.prop(self, 'export_cameras')
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_export.py b/io_scene_gltf2/blender/exp/gltf2_blender_export.py
index 071b4884..ad08a851 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_export.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_export.py
@@ -23,6 +23,7 @@ from io_scene_gltf2.blender.exp import gltf2_blender_gather
 from io_scene_gltf2.blender.exp.gltf2_blender_gltf2_exporter import GlTF2Exporter
 from io_scene_gltf2.io.com.gltf2_io_debug import print_console, print_newline
 from io_scene_gltf2.io.exp import gltf2_io_export
+from io_scene_gltf2.io.exp import gltf2_io_draco_compression_extension
 
 
 def save(context, export_settings):
@@ -66,6 +67,11 @@ def __get_copyright(export_settings):
 
 def __gather_gltf(exporter, export_settings):
     scenes, animations = gltf2_blender_gather.gather_gltf2(export_settings)
+
+    if export_settings['gltf_draco_mesh_compression']:
+        gltf2_io_draco_compression_extension.compress_scene_primitives(scenes, export_settings)
+        exporter.add_draco_extension()
+
     for scene in scenes:
         exporter.add_scene(scene)
     for animation in animations:
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 ea26eb1c..7d4d3a80 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
@@ -135,6 +135,15 @@ class GlTF2Exporter:
         if is_glb:
             return self.__buffer.to_bytes()
 
+    def add_draco_extension(self):
+        """
+        Register Draco extension as *used* and *required*.
+
+        :return:
+        """
+        self.__gltf.extensions_required.append('KHR_draco_mesh_compression')
+        self.__gltf.extensions_used.append('KHR_draco_mesh_compression')
+
     def finalize_images(self, output_path):
         """
         Write all images.
diff --git a/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py b/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py
new file mode 100644
index 00000000..845e2d2d
--- /dev/null
+++ b/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py
@@ -0,0 +1,212 @@
+import bpy
+import sys
+from ctypes import *
+from pathlib import Path
+
+from io_scene_gltf2.io.exp.gltf2_io_binary_data import BinaryData
+
+
+def dll_path() -> Path:
+    """
+    Get the DLL path depending on the underlying platform.
+    :return: DLL path.
+    """
+    lib_name = 'extern_draco'
+    blender_root = Path(bpy.app.binary_path).parent
+    python_lib = Path('2.80/python/lib')
+    paths = {
+        'win32': blender_root/python_lib/'site-packages'/'{}.dll'.format(lib_name),
+        'linux': blender_root/python_lib/'python3.7'/'site-packages'/'lib{}.so'.format(lib_name),
+        'darwin': blender_root.parent/'Resources'/python_lib/'python3.7'/'site-packages'/'lib{}.dylib'.format(lib_name)
+    }
+
+    path = paths.get(sys.platform)
+    return path if path is not None else ''
+
+
+def dll_exists() -> bool:
+    """
+    Checks whether the DLL path exists.
+    :return: True if the DLL exists.
+    """
+    exists = dll_path().exists()
+    print("'{}' ".format(dll_path().absolute()) + ("exists, draco mesh compression is available" if exists else
+                                                   "does not exist, draco mesh compression not available"))
+    return exists
+
+
+def compress_scene_primitives(scenes, export_settings):
+    """
+    Handles draco compression.
+    Invoked after data has been gathered, but before scenes get traversed.
+    Moves position, normal and texture coordinate attributes into a Draco compressed buffer.
+    """
+
+    # Load DLL and setup function signatures.
+    # Nearly all functions take the compressor as the first argument.
+    dll = cdll.LoadLibrary(str(dll_path().resolve()))
+
+    dll.createCompressor.restype = c_void_p
+    dll.createCompressor.argtypes = []
+
+    dll.setCompressionLevel.restype = None
+    dll.setCompressionLevel.argtypes = [c_void_p, c_uint32]
+
+    dll.setPositionQuantizationBits.restype = None
+    dll.setPositionQuantizationBits.argtypes = [c_void_p, c_uint32]
+
+    dll.setNormalQuantizationBits.restype = None
+    dll.setNormalQuantizationBits.argtypes = [c_void_p, c_uint32]
+
+    dll.setTexCoordQuantizationBits.restype = None
+    dll.setTexCoordQuantizationBits.argtypes = [c_void_p, c_uint32]
+
+    dll.compress.restype = c_bool
+    dll.compress.argtypes = [c_void_p]
+
+    dll.compressedSize.restype = c_uint64
+    dll.compressedSize.argtypes = [c_void_p]
+
+    dll.disposeCompressor.restype = None
+    dll.disposeCompressor.argtypes = [c_void_p]
+
+    dll.setFaces.restype = None
+    dll.setFaces.argtypes = [c_void_p, c_uint32, c_uint32, c_void_p]
+
+    dll.addPositionAttribute.restype = None
+    dll.addPositionAttribute.argtypes = [c_void_p, c_uint32, c_char_p]
+
+    dll

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list