Browse Source

Merge pull request #1503 from Palmer-JC/master

Blender Exporter 5.1.0
David Catuhe 8 years ago
parent
commit
0f7f8486c9

BIN
Exporters/Blender/Blender2Babylon-5.1.zip


+ 1 - 1
Exporters/Blender/readme.md

@@ -56,7 +56,7 @@ For a discussion of Tower of Babel exporter, along with the difference this expo
  * Child materials
  * 32 bit vertex limit for multi-materials
 * **Textures**
- * Name
+ * Name(s) - Multiples for compressed texture prioritization
  * Associated file
  * Level
  * Use alpha

+ 2 - 1
Exporters/Blender/src/__init__.py

@@ -1,7 +1,7 @@
 bl_info = {
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (5, 0, 7),
+    'version': (5, 1, 0),
     'blender': (2, 76, 0),
     'location': 'File > Export > Babylon.js (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',
@@ -68,6 +68,7 @@ class JsonMain(bpy.types.Operator, ExportHelper):
     filename_ext = '.babylon'            # used as the extension on file selector
 
     filepath = bpy.props.StringProperty(subtype = 'FILE_PATH') # assigned once the file selector returns
+    filter_glob = bpy.props.StringProperty(name='.babylon',default='*.babylon', options={'HIDDEN'})
     
     def execute(self, context):
         from .json_exporter import JsonExporter

+ 33 - 17
Exporters/Blender/src/exporter_settings_panel.py

@@ -1,6 +1,9 @@
 from .package_level import *
 
 import bpy
+LEGACY      = 'LEGACY'
+INLINE      = 'INLINE'
+PRIORITIZED = 'PRIORITIZED'
 # Panel displayed in Scene Tab of properties, so settings can be saved in a .blend file
 class ExporterSettingsPanel(bpy.types.Panel):
     bl_label = get_title()
@@ -9,13 +12,13 @@ class ExporterSettingsPanel(bpy.types.Panel):
     bl_context = 'scene'
 
     bpy.types.Scene.export_onlySelectedLayer = bpy.props.BoolProperty(
-        name="Export only selected layers",
-        description="Export only selected layers",
+        name='Export only selected layers',
+        description='Export only selected layers',
         default = False,
         )
     bpy.types.Scene.export_flatshadeScene = bpy.props.BoolProperty(
-        name="Flat shade entire scene",
-        description="Use face normals on all meshes.  Increases vertices.",
+        name='Flat shade entire scene',
+        description='Use face normals on all meshes.  Increases vertices.',
         default = False,
         )
     bpy.types.Scene.attachedSound = bpy.props.StringProperty(
@@ -33,18 +36,28 @@ class ExporterSettingsPanel(bpy.types.Panel):
         description='',
         default = True
         )
-    bpy.types.Scene.inlineTextures = bpy.props.BoolProperty(
-        name="inline",
-        description="turn textures into encoded strings, for direct inclusion into source code",
-        default = False,
+    bpy.types.Scene.textureMethod = bpy.props.EnumProperty(
+        name='Method',
+        description='How are textures to be implemented',
+        items = (
+                 (LEGACY     , 'Legacy'     , 'Just the single Blender texture'),
+                 (INLINE     , 'Inline'     , 'Place a base64 version of texture directly in the output'),
+                 (PRIORITIZED, 'Prioritized', 'Allow various compressed texture formats to be tried first')
+                ),
+        default = LEGACY
+    )
+    bpy.types.Scene.texturePriority = bpy.props.StringProperty(
+        name='Order',
+        description='Space delimited list of extensions to try\nnot including format supplied by Blender\nwhich will be last.',
+        default = '.ASTC .DDS .ETC'
         )
     bpy.types.Scene.textureDir = bpy.props.StringProperty(
-        name='sub-directory',
+        name='Sub-directory',
         description='The path below the output directory to write texture files (any separators OS dependent)',
         default = ''
         )
     bpy.types.Scene.ignoreIKBones = bpy.props.BoolProperty(
-        name="Ignore IK Bones",
+        name='Ignore IK Bones',
         description="Do not export bones with either '.ik' or 'ik.'(not case sensitive) in the name",
         default = False,
         )
@@ -53,16 +66,19 @@ class ExporterSettingsPanel(bpy.types.Panel):
         layout = self.layout
 
         scene = context.scene
-        layout.prop(scene, "export_onlySelectedLayer")
-        layout.prop(scene, "export_flatshadeScene")
-        layout.prop(scene, "ignoreIKBones")
+        layout.prop(scene, 'export_onlySelectedLayer')
+        layout.prop(scene, 'export_flatshadeScene')
+        layout.prop(scene, 'ignoreIKBones')
 
         box = layout.box()
-        box.label(text='Texture Location:')
-        box.prop(scene, "inlineTextures")
+        box.label(text='Texture Options:')
+        box.prop(scene, 'textureMethod')
+        row = box.row()
+        row.enabled = scene.textureMethod == PRIORITIZED
+        row.prop(scene, 'texturePriority')
         row = box.row()
-        row.enabled = not scene.inlineTextures
-        row.prop(scene, "textureDir")
+        row.enabled = scene.textureMethod != INLINE
+        row.prop(scene, 'textureDir')
 
         box = layout.box()
         box.prop(scene, 'attachedSound')

+ 6 - 5
Exporters/Blender/src/json_exporter.py

@@ -32,20 +32,21 @@ class JsonExporter:
 
             # assign texture location, purely temporary if inlining
             self.textureDir = path.dirname(filepath)
-            if not scene.inlineTextures:
+            if scene.textureMethod != INLINE:
                 self.textureDir = path.join(self.textureDir, scene.textureDir)
                 if not path.isdir(self.textureDir):
                     makedirs(self.textureDir)
-                    Logger.warn("Texture sub-directory did not already exist, created: " + self.textureDir)
+                    Logger.warn('Texture sub-directory did not already exist, created: ' + self.textureDir)
 
             Logger.log('========= Conversion from Blender to Babylon.js =========', 0)
             Logger.log('Scene settings used:', 1)
             Logger.log('selected layers only:  ' + format_bool(scene.export_onlySelectedLayer), 2)
             Logger.log('flat shading entire scene:  ' + format_bool(scene.export_flatshadeScene), 2)
-            Logger.log('inline textures:  ' + format_bool(scene.inlineTextures), 2)
-            if not scene.inlineTextures:
+            Logger.log('texture Method:  ' + scene.textureMethod, 2)
+            if scene.textureMethod != INLINE:
                 Logger.log('texture directory:  ' + self.textureDir, 2)
-
+            if scene.textureMethod == PRIORITIZED:
+                Logger.log('Priority Order:  ' + scene.texturePriority)
             self.world = World(scene)
 
             bpy.ops.screen.animation_cancel()

+ 32 - 9
Exporters/Blender/src/material.py

@@ -1,3 +1,4 @@
+from .exporter_settings_panel import *
 from .logger import *
 from .package_level import *
 
@@ -77,16 +78,16 @@ class Texture:
         # always write the file out, since base64 encoding is easiest from a file
         try:
             imageFilepath = path.normpath(bpy.path.abspath(image.filepath))
-            basename = path.basename(imageFilepath)
+            self.fileNoPath = path.basename(imageFilepath)
 
             internalImage = image.packed_file or wasBaked
 
             # when coming from either a packed image or a baked image, then save_render
             if internalImage:
-                if exporter.scene.inlineTextures:
-                    textureFile = path.join(exporter.textureDir, basename + "temp")
+                if exporter.scene.textureMethod == INLINE:
+                    textureFile = path.join(exporter.textureDir, self.fileNoPath + 'temp')
                 else:
-                    textureFile = path.join(exporter.textureDir, basename)
+                    textureFile = path.join(exporter.textureDir, self.fileNoPath)
 
                 image.save_render(textureFile)
 
@@ -99,7 +100,7 @@ class Texture:
             ex = exc_info()
             Logger.warn('Error encountered processing image file:  ' + ', Error:  '+ str(ex[1]))
 
-        if exporter.scene.inlineTextures:
+        if exporter.scene.textureMethod == INLINE:
             # base64 is easiest from a file, so sometimes a temp file was made above;  need to delete those
             with open(textureFile, "rb") as image_file:
                 asString = b64encode(image_file.read()).decode()
@@ -108,9 +109,18 @@ class Texture:
             if internalImage:
                 remove(textureFile)
 
+        # build priority Order
+        if exporter.scene.textureMethod == PRIORITIZED:
+            nameNoExtension = self.fileNoPath.rpartition('.')[0]
+            self.priorityNames = []
+            for ext in exporter.scene.texturePriority.split():
+                self.priorityNames.append(nameNoExtension + ext)
+
+            # add blend image last
+            self.priorityNames.append(self.fileNoPath)
+
         # capture texture attributes
         self.slot = slot
-        self.name = basename
         self.level = level
 
         if (texture and texture.mapping == 'CUBE'):
@@ -144,7 +154,22 @@ class Texture:
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def to_scene_file(self, file_handler):
         file_handler.write(', \n"' + self.slot + '":{')
-        write_string(file_handler, 'name', self.name, True)
+        if hasattr(self,'encoded_URI'):
+            write_string(file_handler, 'base64String', self.encoded_URI)
+
+        elif hasattr(self,'priorityNames'):
+            file_handler.write('"name":[')
+            first = True
+            for name in self.priorityNames:
+                if first == False:
+                    file_handler.write(',')
+                file_handler.write('"' + name + '"')
+                first = False
+            file_handler.write(']')
+
+        else:
+            write_string(file_handler, 'name', self.fileNoPath, True)
+
         write_float(file_handler, 'level', self.level)
         write_float(file_handler, 'hasAlpha', self.hasAlpha)
         write_int(file_handler, 'coordinatesMode', self.coordinatesMode)
@@ -158,8 +183,6 @@ class Texture:
         write_int(file_handler, 'wrapU', self.wrapU)
         write_int(file_handler, 'wrapV', self.wrapV)
         write_int(file_handler, 'coordinatesIndex', self.coordinatesIndex)
-        if hasattr(self,'encoded_URI'):
-            write_string(file_handler, 'base64String', self.encoded_URI)
         file_handler.write('}')
 #===============================================================================
 # need to evaluate the need to bake a mesh before even starting; class also stores specific types of bakes

+ 5 - 0
src/Materials/Textures/babylon.texture.ts

@@ -301,6 +301,11 @@
                     var texture: Texture;
                     if (parsedTexture.base64String) {
                         texture = Texture.CreateFromBase64String(parsedTexture.base64String, parsedTexture.name, scene);
+                    } else if (parsedTexture.name instanceof Array) {
+                        for (var i = 0, len = parsedTexture.name.length; i < len; i++) {
+                            parsedTexture.name[i] = rootUrl + parsedTexture.name[i];
+                        }
+                        texture = new Texture(parsedTexture.name, scene);
                     } else {
                         texture = new Texture(rootUrl + parsedTexture.name, scene);
                     }