Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py')
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_image.py173
1 files changed, 108 insertions, 65 deletions
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
index b0fb2c25..8e441f9c 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
@@ -42,7 +42,12 @@ def gather_image(
mime_type = __gather_mime_type(blender_shader_sockets, image_data, export_settings)
name = __gather_name(image_data, export_settings)
- uri = __gather_uri(image_data, mime_type, name, export_settings)
+ if image_data.original is None:
+ uri = __gather_uri(image_data, mime_type, name, export_settings)
+ else:
+ # Retrieve URI relative to exported glTF files
+ uri = __gather_original_uri(image_data.original.filepath, export_settings)
+
buffer_view = __gather_buffer_view(image_data, mime_type, name, export_settings)
image = __make_image(
@@ -59,6 +64,27 @@ def gather_image(
return image
+def __gather_original_uri(original_uri, export_settings):
+
+ def _path_to_uri(path):
+ import urllib
+ path = os.path.normpath(path)
+ path = path.replace(os.sep, '/')
+ return urllib.parse.quote(path)
+
+ path_to_image = bpy.path.abspath(original_uri)
+ if not os.path.exists(path_to_image): return None
+ try:
+ rel_path = os.path.relpath(
+ path_to_image,
+ start=export_settings[gltf2_blender_export_keys.FILE_DIRECTORY],
+ )
+ except ValueError:
+ # eg. because no relative path between C:\ and D:\ on Windows
+ return None
+ return _path_to_uri(rel_path)
+
+
@cached
def __make_image(buffer_view, extensions, extras, mime_type, name, uri, export_settings):
return gltf2_io.Image(
@@ -99,7 +125,12 @@ def __gather_mime_type(sockets, export_image, export_settings):
return "image/png"
if export_settings["gltf_image_format"] == "AUTO":
- image = export_image.blender_image()
+ if export_image.original is None: # We are going to create a new image
+ image = export_image.blender_image()
+ else:
+ # Using original image
+ image = export_image.original
+
if image is not None and __is_blender_image_a_jpeg(image):
return "image/jpeg"
return "image/png"
@@ -109,30 +140,33 @@ def __gather_mime_type(sockets, export_image, export_settings):
def __gather_name(export_image, export_settings):
- # Find all Blender images used in the ExportImage
- imgs = []
- for fill in export_image.fills.values():
- if isinstance(fill, FillImage):
- img = fill.image
- if img not in imgs:
- imgs.append(img)
-
- # If all the images have the same path, use the common filename
- filepaths = set(img.filepath for img in imgs)
- if len(filepaths) == 1:
- filename = os.path.basename(list(filepaths)[0])
- name, extension = os.path.splitext(filename)
- if extension.lower() in ['.png', '.jpg', '.jpeg']:
- if name:
- return name
-
- # Combine the image names: img1-img2-img3
- names = []
- for img in imgs:
- name, extension = os.path.splitext(img.name)
- names.append(name)
- name = '-'.join(names)
- return name or 'Image'
+ if export_image.original is None:
+ # Find all Blender images used in the ExportImage
+ imgs = []
+ for fill in export_image.fills.values():
+ if isinstance(fill, FillImage):
+ img = fill.image
+ if img not in imgs:
+ imgs.append(img)
+
+ # If all the images have the same path, use the common filename
+ filepaths = set(img.filepath for img in imgs)
+ if len(filepaths) == 1:
+ filename = os.path.basename(list(filepaths)[0])
+ name, extension = os.path.splitext(filename)
+ if extension.lower() in ['.png', '.jpg', '.jpeg']:
+ if name:
+ return name
+
+ # Combine the image names: img1-img2-img3
+ names = []
+ for img in imgs:
+ name, extension = os.path.splitext(img.name)
+ names.append(name)
+ name = '-'.join(names)
+ return name or 'Image'
+ else:
+ return export_image.original.name
@cached
@@ -161,46 +195,55 @@ def __get_image_data(sockets, export_settings) -> ExportImage:
result.shader_node.image))
continue
- # rudimentarily try follow the node tree to find the correct image data.
- src_chan = Channel.R
- for elem in result.path:
- if isinstance(elem.from_node, bpy.types.ShaderNodeSeparateRGB):
- src_chan = {
- 'R': Channel.R,
- 'G': Channel.G,
- 'B': Channel.B,
- }[elem.from_socket.name]
- if elem.from_socket.name == 'Alpha':
- src_chan = Channel.A
-
- dst_chan = None
-
- # some sockets need channel rewriting (gltf pbr defines fixed channels for some attributes)
- if socket.name == 'Metallic':
- dst_chan = Channel.B
- elif socket.name == 'Roughness':
- dst_chan = Channel.G
- elif socket.name == 'Occlusion':
- dst_chan = Channel.R
- elif socket.name == 'Alpha':
- dst_chan = Channel.A
- elif socket.name == 'Clearcoat':
- dst_chan = Channel.R
- elif socket.name == 'Clearcoat Roughness':
- dst_chan = Channel.G
-
- if dst_chan is not None:
- composed_image.fill_image(result.shader_node.image, dst_chan, src_chan)
-
- # Since metal/roughness are always used together, make sure
- # the other channel is filled.
- if socket.name == 'Metallic' and not composed_image.is_filled(Channel.G):
- composed_image.fill_white(Channel.G)
- elif socket.name == 'Roughness' and not composed_image.is_filled(Channel.B):
- composed_image.fill_white(Channel.B)
+ # Assume that user know what he does, and that channels/images are already combined correctly for pbr
+ # If not, we are going to keep only the first texture found
+ # Example : If user set up 2 or 3 different textures for Metallic / Roughness / Occlusion
+ # Only 1 will be used at export
+ # This Warning is displayed in UI of this option
+ if export_settings['gltf_keep_original_textures']:
+ composed_image = ExportImage.from_original(result.shader_node.image)
+
else:
- # copy full image...eventually following sockets might overwrite things
- composed_image = ExportImage.from_blender_image(result.shader_node.image)
+ # rudimentarily try follow the node tree to find the correct image data.
+ src_chan = Channel.R
+ for elem in result.path:
+ if isinstance(elem.from_node, bpy.types.ShaderNodeSeparateRGB):
+ src_chan = {
+ 'R': Channel.R,
+ 'G': Channel.G,
+ 'B': Channel.B,
+ }[elem.from_socket.name]
+ if elem.from_socket.name == 'Alpha':
+ src_chan = Channel.A
+
+ dst_chan = None
+
+ # some sockets need channel rewriting (gltf pbr defines fixed channels for some attributes)
+ if socket.name == 'Metallic':
+ dst_chan = Channel.B
+ elif socket.name == 'Roughness':
+ dst_chan = Channel.G
+ elif socket.name == 'Occlusion':
+ dst_chan = Channel.R
+ elif socket.name == 'Alpha':
+ dst_chan = Channel.A
+ elif socket.name == 'Clearcoat':
+ dst_chan = Channel.R
+ elif socket.name == 'Clearcoat Roughness':
+ dst_chan = Channel.G
+
+ if dst_chan is not None:
+ composed_image.fill_image(result.shader_node.image, dst_chan, src_chan)
+
+ # Since metal/roughness are always used together, make sure
+ # the other channel is filled.
+ if socket.name == 'Metallic' and not composed_image.is_filled(Channel.G):
+ composed_image.fill_white(Channel.G)
+ elif socket.name == 'Roughness' and not composed_image.is_filled(Channel.B):
+ composed_image.fill_white(Channel.B)
+ else:
+ # copy full image...eventually following sockets might overwrite things
+ composed_image = ExportImage.from_blender_image(result.shader_node.image)
return composed_image