diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py index eb51d6d53..14cc523a0 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py @@ -318,11 +318,19 @@ def previous_node(socket): return prev_socket.node return None -#TODOExt is this the same as __get_tex_from_socket from gather_image ? -def has_image_node_from_socket(socket): +def get_tex_from_socket(socket): result = gltf2_blender_search_node_tree.from_socket( socket, gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeTexImage)) if not result: - return False - return True + return None + if result[0].shader_node.image is None: + return None + return result[0] + +def has_image_node_from_socket(socket): + return get_tex_from_socket(socket) is not None + +def image_tex_is_valid_from_socket(socket): + res = get_tex_from_socket(socket) + return res is not None and res.shader_node.image is not None and res.shader_node.image.channels != 0 diff --git a/addons/io_scene_gltf2/blender/exp/material/extensions/gltf2_blender_gather_materials_specular.py b/addons/io_scene_gltf2/blender/exp/material/extensions/gltf2_blender_gather_materials_specular.py index 98f6d99e0..66b0f6f90 100644 --- a/addons/io_scene_gltf2/blender/exp/material/extensions/gltf2_blender_gather_materials_specular.py +++ b/addons/io_scene_gltf2/blender/exp/material/extensions/gltf2_blender_gather_materials_specular.py @@ -17,7 +17,8 @@ from .....io.com.gltf2_io_constants import GLTF_IOR from ....exp import gltf2_blender_get from ....com.gltf2_blender_default import BLENDER_SPECULAR, BLENDER_SPECULAR_TINT -from ...material import gltf2_blender_gather_texture_info +from ...material.gltf2_blender_gather_texture_info import gather_texture_info +from ...gltf2_blender_get import image_tex_is_valid_from_socket def export_original_specular(blender_material, export_settings): specular_extension = {} @@ -46,7 +47,7 @@ def export_original_specular(blender_material, export_settings): # Texture if gltf2_blender_get.has_image_node_from_socket(original_specular_socket): - original_specular_texture, original_specular_use_active_uvmap, _ = gltf2_blender_gather_texture_info.gather_texture_info( + original_specular_texture, original_specular_use_active_uvmap, _ = gather_texture_info( original_specular_socket, (original_specular_socket,), export_settings, @@ -68,7 +69,7 @@ def export_original_specular(blender_material, export_settings): # Texture if gltf2_blender_get.has_image_node_from_socket(original_specularcolor_socket): - original_specularcolor_texture, original_specularcolor_use_active_uvmap, _ = gltf2_blender_gather_texture_info.gather_texture_info( + original_specularcolor_texture, original_specularcolor_use_active_uvmap, _ = gather_texture_info( original_specularcolor_socket, (original_specularcolor_socket,), export_settings, @@ -96,12 +97,11 @@ def export_specular(blender_material, export_settings): if base_color_socket is None: return None, None - # TODOExt replace by __has_image_node_from_socket calls - specular_not_linked = isinstance(specular_socket, bpy.types.NodeSocket) and not specular_socket.is_linked - specular_tint_not_linked = isinstance(specular_tint_socket, bpy.types.NodeSocket) and not specular_tint_socket.is_linked - base_color_not_linked = isinstance(base_color_socket, bpy.types.NodeSocket) and not base_color_socket.is_linked - transmission_not_linked = isinstance(transmission_socket, bpy.types.NodeSocket) and not transmission_socket.is_linked - ior_not_linked = isinstance(ior_socket, bpy.types.NodeSocket) and not ior_socket.is_linked + specular_not_linked = not image_tex_is_valid_from_socket(specular_socket) + specular_tint_not_linked = not image_tex_is_valid_from_socket(specular_tint_socket) + base_color_not_linked = not image_tex_is_valid_from_socket(base_color_socket) + transmission_not_linked = not image_tex_is_valid_from_socket(transmission_socket) + ior_not_linked = not image_tex_is_valid_from_socket(ior_socket) specular = specular_socket.default_value if specular_not_linked else None specular_tint = specular_tint_socket.default_value if specular_tint_not_linked else None @@ -159,7 +159,7 @@ def normalize(c): if base_color_not_linked: primary_socket = transmission_socket - specularColorTexture, use_active_uvmap, specularColorFactor = gltf2_blender_gather_texture_info.gather_texture_info( + specularColorTexture, use_active_uvmap, specularColorFactor = gather_texture_info( primary_socket, sockets, export_settings, diff --git a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_image.py b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_image.py index 7ae46adf1..1e895ee00 100644 --- a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_image.py +++ b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_image.py @@ -22,8 +22,8 @@ from ....io.com import gltf2_io_debug from ....io.exp.gltf2_io_user_extensions import export_user_extensions from ..gltf2_blender_gather_cache import cached -from . import gltf2_blender_search_node_tree from .extensions.gltf2_blender_image import Channel, ExportImage, FillImage +from ..gltf2_blender_get import get_tex_from_socket @cached def gather_image( @@ -188,7 +188,7 @@ def __get_image_data(sockets, export_settings) -> ExportImage: # For shared resources, such as images, we just store the portion of data that is needed in the glTF property # in a helper class. During generation of the glTF in the exporter these will then be combined to actual binary # resources. - results = [__get_tex_from_socket(socket, export_settings) for socket in sockets] + results = [get_tex_from_socket(socket) for socket in sockets] # Check if we need a simple mapping or more complex calculation if any([socket.name == "Specular" and socket.node.type == "BSDF_PRINCIPLED" for socket in sockets]): @@ -281,7 +281,7 @@ def __get_image_data_specular(sockets, results, export_settings) -> ExportImage: composed_image.store_data("ior", sockets[4].default_value, type="Data") - results = [__get_tex_from_socket(socket, export_settings) for socket in sockets[:-1]] #Do not retrieve IOR --> No texture allowed + results = [get_tex_from_socket(socket) for socket in sockets[:-1]] #Do not retrieve IOR --> No texture allowed mapping = { 0: "specular", @@ -291,7 +291,7 @@ def __get_image_data_specular(sockets, results, export_settings) -> ExportImage: } for idx, result in enumerate(results): - if __get_tex_from_socket(sockets[idx], export_settings): + if get_tex_from_socket(sockets[idx]): composed_image.store_data(mapping[idx], result.shader_node.image, type="Image") @@ -318,16 +318,6 @@ def __get_image_data_specular(sockets, results, export_settings) -> ExportImage: return composed_image -# TODOExt deduplicate -@cached -def __get_tex_from_socket(blender_shader_socket: bpy.types.NodeSocket, export_settings): - result = gltf2_blender_search_node_tree.from_socket( - blender_shader_socket, - gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeTexImage)) - if not result: - return None - return result[0] - def __is_blender_image_a_jpeg(image: bpy.types.Image) -> bool: if image.source != 'FILE': diff --git a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_pbr_metallic_roughness.py b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_pbr_metallic_roughness.py index 3d245c81b..de2663873 100644 --- a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_pbr_metallic_roughness.py +++ b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_pbr_metallic_roughness.py @@ -18,8 +18,8 @@ from ....io.exp.gltf2_io_user_extensions import export_user_extensions from ...exp import gltf2_blender_get from ..gltf2_blender_gather_cache import cached -from . import gltf2_blender_search_node_tree -from . import gltf2_blender_gather_texture_info +from ..gltf2_blender_get import image_tex_is_valid_from_socket +from .gltf2_blender_gather_texture_info import gather_texture_info @cached def gather_material_pbr_metallic_roughness(blender_material, orm_texture, export_settings): @@ -103,12 +103,12 @@ def __gather_base_color_texture(blender_material, export_settings): # keep sockets that have some texture : color and/or alpha inputs = tuple( socket for socket in [base_color_socket, alpha_socket] - if socket is not None and __has_image_node_from_socket(socket) + if socket is not None and image_tex_is_valid_from_socket(socket) ) if not inputs: return None, None, None - return gltf2_blender_gather_texture_info.gather_texture_info(inputs[0], inputs, export_settings) + return gather_texture_info(inputs[0], inputs, export_settings) def __gather_extensions(blender_material, export_settings): @@ -136,12 +136,12 @@ def __gather_metallic_roughness_texture(blender_material, orm_texture, export_se metallic_socket = gltf2_blender_get.get_socket(blender_material, "Metallic") roughness_socket = gltf2_blender_get.get_socket(blender_material, "Roughness") - hasMetal = metallic_socket is not None and __has_image_node_from_socket(metallic_socket) - hasRough = roughness_socket is not None and __has_image_node_from_socket(roughness_socket) + hasMetal = metallic_socket is not None and image_tex_is_valid_from_socket(metallic_socket) + hasRough = roughness_socket is not None and image_tex_is_valid_from_socket(roughness_socket) if not hasMetal and not hasRough: metallic_roughness = gltf2_blender_get.get_socket_old(blender_material, "MetallicRoughness") - if metallic_roughness is None or not __has_image_node_from_socket(metallic_roughness): + if metallic_roughness is None or not image_tex_is_valid_from_socket(metallic_roughness): return None, None, None texture_input = (metallic_roughness,) elif not hasMetal: @@ -151,7 +151,7 @@ def __gather_metallic_roughness_texture(blender_material, orm_texture, export_se else: texture_input = (metallic_socket, roughness_socket) - return gltf2_blender_gather_texture_info.gather_texture_info( + return gather_texture_info( texture_input[0], orm_texture or texture_input, export_settings, @@ -170,14 +170,6 @@ def __gather_roughness_factor(blender_material, export_settings): return fac if fac != 1 else None return None -def __has_image_node_from_socket(socket): - result = gltf2_blender_search_node_tree.from_socket( - socket, - gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeTexImage)) - if not result: - return False - return True - def get_default_pbr_for_emissive_node(): return gltf2_io.MaterialPBRMetallicRoughness( base_color_factor=[0.0,0.0,0.0,1.0], diff --git a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_texture.py b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_texture.py index b995094ff..e113198af 100644 --- a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_texture.py +++ b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_texture.py @@ -19,7 +19,7 @@ from ....io.com import gltf2_io from ..gltf2_blender_gather_cache import cached from ..gltf2_blender_gather_sampler import gather_sampler -from . import gltf2_blender_search_node_tree +from ..gltf2_blender_get import get_tex_from_socket from . import gltf2_blender_gather_image @cached @@ -77,7 +77,7 @@ def __gather_name(blender_shader_sockets, export_settings): def __gather_sampler(blender_shader_sockets, export_settings): - shader_nodes = [__get_tex_from_socket(socket) for socket in blender_shader_sockets] + shader_nodes = [get_tex_from_socket(socket) for socket in blender_shader_sockets] if len(shader_nodes) > 1: gltf2_io_debug.print_console("WARNING", "More than one shader node tex image used for a texture. " @@ -90,14 +90,3 @@ def __gather_sampler(blender_shader_sockets, export_settings): def __gather_source(blender_shader_sockets, export_settings): return gltf2_blender_gather_image.gather_image(blender_shader_sockets, export_settings) - -# Helpers - -# TODOExt deduplicate -def __get_tex_from_socket(socket): - result = gltf2_blender_search_node_tree.from_socket( - socket, - gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeTexImage)) - if not result: - return None - return result[0] diff --git a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_texture_info.py b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_texture_info.py index 2369d4c1b..ec0a4d84d 100644 --- a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_texture_info.py +++ b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_texture_info.py @@ -18,7 +18,7 @@ from ....io.com.gltf2_io_extensions import Extension from ....io.exp.gltf2_io_user_extensions import export_user_extensions from ...exp import gltf2_blender_get -from ..gltf2_blender_get import previous_node +from ..gltf2_blender_get import previous_node, get_tex_from_socket from ..gltf2_blender_gather_sampler import detect_manual_uv_wrapping from ..gltf2_blender_gather_cache import cached from . import gltf2_blender_gather_texture @@ -82,7 +82,7 @@ def __gather_texture_info_helper( def __filter_texture_info(primary_socket, blender_shader_sockets, filter_type, export_settings): if primary_socket is None: return False - if __get_tex_from_socket(primary_socket) is None: + if get_tex_from_socket(primary_socket) is None: return False if not blender_shader_sockets: return False @@ -90,12 +90,12 @@ def __filter_texture_info(primary_socket, blender_shader_sockets, filter_type, e return False if filter_type == "ALL": # Check that all sockets link to texture - if any([__get_tex_from_socket(socket) is None for socket in blender_shader_sockets]): + if any([get_tex_from_socket(socket) is None for socket in blender_shader_sockets]): # sockets do not lead to a texture --> discard return False elif filter_type == "ANY": # Check that at least one socket link to texture - if all([__get_tex_from_socket(socket) is None for socket in blender_shader_sockets]): + if all([get_tex_from_socket(socket) is None for socket in blender_shader_sockets]): return False elif filter_type == "NONE": # No check @@ -158,7 +158,7 @@ def __gather_texture_transform_and_tex_coord(primary_socket, export_settings): # # The [UV Wrapping] is for wrap modes like MIRROR that use nodes, # [Mapping] is for KHR_texture_transform, and [UV Map] is for texCoord. - blender_shader_node = __get_tex_from_socket(primary_socket).shader_node + blender_shader_node = get_tex_from_socket(primary_socket).shader_node # Skip over UV wrapping stuff (it goes in the sampler) result = detect_manual_uv_wrapping(blender_shader_node) @@ -188,17 +188,6 @@ def __gather_texture_transform_and_tex_coord(primary_socket, export_settings): return texture_transform, texcoord_idx or None, use_active_uvmap -# TODOExt deduplicate -def __get_tex_from_socket(socket): - result = gltf2_blender_search_node_tree.from_socket( - socket, - gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeTexImage)) - if not result: - return None - if result[0].shader_node.image is None: - return None - return result[0] - def check_same_size_images( blender_shader_sockets: typing.Tuple[bpy.types.NodeSocket], @@ -209,7 +198,7 @@ def check_same_size_images( sizes = set() for socket in blender_shader_sockets: - tex = __get_tex_from_socket(socket) + tex = get_tex_from_socket(socket) if tex is None: return False size = tex.shader_node.image.size diff --git a/tests/scenes/01_factors.blend b/tests/scenes/01_factors.blend index 50710711a..acdf80053 100644 Binary files a/tests/scenes/01_factors.blend and b/tests/scenes/01_factors.blend differ