Skip to content
Snippets Groups Projects
Commit 872e3e6a authored by Julien Duroure's avatar Julien Duroure
Browse files

glTF exporter: image options change

parent 3049742f
No related branches found
No related tags found
No related merge requests found
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
bl_info = { bl_info = {
'name': 'glTF 2.0 format', 'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', 'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (1, 2, 2), "version": (1, 2, 3),
'blender': (2, 81, 6), 'blender': (2, 81, 6),
'location': 'File > Import-Export', 'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0', 'description': 'Import-Export as glTF 2.0',
...@@ -113,18 +113,18 @@ class ExportGLTF2_Base: ...@@ -113,18 +113,18 @@ class ExportGLTF2_Base:
export_image_format: EnumProperty( export_image_format: EnumProperty(
name='Images', name='Images',
items=(('NAME', 'Automatic', items=(('AUTO', 'Automatic',
'Determine the image format from the blender image name'), 'Save PNGs as PNGs and JPEGs as JPEGs.\n'
'If neither one, use PNG'),
('JPEG', 'JPEG Format (.jpg)', ('JPEG', 'JPEG Format (.jpg)',
'Encode and save textures as .jpg files. Be aware of a possible loss in quality'), 'Save images as JPEGs. (Images that need alpha are saved as PNGs though.)\n'
('PNG', 'PNG Format (.png)', 'Be aware of a possible loss in quality'),
'Encode and save textures as .png files')
), ),
description=( description=(
'Output format for images. PNG is lossless and generally preferred, but JPEG might be preferable for web ' 'Output format for images. PNG is lossless and generally preferred, but JPEG might be preferable for web '
'applications due to the smaller file size' 'applications due to the smaller file size'
), ),
default='NAME' default='AUTO'
) )
export_texture_dir: StringProperty( export_texture_dir: StringProperty(
......
...@@ -42,7 +42,7 @@ def gather_image( ...@@ -42,7 +42,7 @@ def gather_image(
# The export image has no data # The export image has no data
return None return None
mime_type = __gather_mime_type(blender_shader_sockets_or_texture_slots, export_settings) mime_type = __gather_mime_type(blender_shader_sockets_or_texture_slots, image_data, export_settings)
name = __gather_name(blender_shader_sockets_or_texture_slots, export_settings) name = __gather_name(blender_shader_sockets_or_texture_slots, export_settings)
uri = __gather_uri(image_data, mime_type, name, export_settings) uri = __gather_uri(image_data, mime_type, name, export_settings)
...@@ -95,27 +95,20 @@ def __gather_extras(sockets_or_slots, export_settings): ...@@ -95,27 +95,20 @@ def __gather_extras(sockets_or_slots, export_settings):
return None return None
def __gather_mime_type(sockets_or_slots, export_settings): def __gather_mime_type(sockets_or_slots, export_image, export_settings):
# force png if Alpha contained so we can export alpha # force png if Alpha contained so we can export alpha
for socket in sockets_or_slots: for socket in sockets_or_slots:
if socket.name == "Alpha": if socket.name == "Alpha":
return "image/png" return "image/png"
if export_settings["gltf_image_format"] == "NAME": if export_settings["gltf_image_format"] == "AUTO":
extension = __get_extension_from_slot(sockets_or_slots, export_settings) image = export_image.blender_image()
extension = extension.lower() if image is not None and image.file_format == 'JPEG':
if extension in [".jpeg", ".jpg", ".png"]: return "image/jpeg"
return {
".jpeg": "image/jpeg",
".jpg": "image/jpeg",
".png": "image/png",
}[extension]
return "image/png" return "image/png"
elif export_settings["gltf_image_format"] == "JPEG": elif export_settings["gltf_image_format"] == "JPEG":
return "image/jpeg" return "image/jpeg"
else:
return "image/png"
def __gather_name(sockets_or_slots, export_settings): def __gather_name(sockets_or_slots, export_settings):
...@@ -246,23 +239,3 @@ def __get_texname_from_slot(sockets_or_slots, export_settings): ...@@ -246,23 +239,3 @@ def __get_texname_from_slot(sockets_or_slots, export_settings):
elif isinstance(sockets_or_slots[0], bpy.types.MaterialTextureSlot): elif isinstance(sockets_or_slots[0], bpy.types.MaterialTextureSlot):
return sockets_or_slots[0].texture.image.name return sockets_or_slots[0].texture.image.name
@cached
def __get_extension_from_slot(sockets_or_slots, export_settings):
if __is_socket(sockets_or_slots):
for socket in sockets_or_slots:
node = __get_tex_from_socket(socket, export_settings)
if node is not None:
image_name = node.shader_node.image.name
filepath = bpy.data.images[image_name].filepath
name, extension = os.path.splitext(filepath)
if extension:
return extension
return '.png'
elif isinstance(sockets_or_slots[0], bpy.types.MaterialTextureSlot):
image_name = sockets_or_slots[0].texture.image.name
filepath = bpy.data.images[image_name].filepath
name, extension = os.path.splitext(filepath)
return extension
...@@ -86,15 +86,18 @@ class ExportImage: ...@@ -86,15 +86,18 @@ class ExportImage:
def empty(self) -> bool: def empty(self) -> bool:
return not self.fills return not self.fills
def blender_image(self) -> Optional[bpy.types.Image]:
"""If there's an existing Blender image we can use,
returns it. Otherwise (if channels need packing),
returns None.
"""
if self.__on_happy_path():
for fill in self.fills.values():
return fill.image
return None
def __on_happy_path(self) -> bool: def __on_happy_path(self) -> bool:
# Whether there is an existing Blender image we can use for this # All src_chans match their dst_chan and come from the same image
# ExportImage because all the channels come from the matching
# channel of that image, eg.
#
# self.fills = {
# Channel.R: FillImage(image=im, src_chan=Channel.R),
# Channel.G: FillImage(image=im, src_chan=Channel.G),
# }
return ( return (
all(isinstance(fill, FillImage) for fill in self.fills.values()) and all(isinstance(fill, FillImage) for fill in self.fills.values()) and
all(dst_chan == fill.src_chan for dst_chan, fill in self.fills.items()) and all(dst_chan == fill.src_chan for dst_chan, fill in self.fills.items()) and
...@@ -115,8 +118,7 @@ class ExportImage: ...@@ -115,8 +118,7 @@ class ExportImage:
return self.__encode_unhappy() return self.__encode_unhappy()
def __encode_happy(self) -> bytes: def __encode_happy(self) -> bytes:
for fill in self.fills.values(): return self.__encode_from_image(self.blender_image())
return self.__encode_from_image(fill.image)
def __encode_unhappy(self) -> bytes: def __encode_unhappy(self) -> bytes:
result = self.__encode_unhappy_with_compositor() result = self.__encode_unhappy_with_compositor()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment