Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1964 - fix check texture image #1966

Merged
merged 2 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions addons/io_scene_gltf2/blender/exp/gltf2_blender_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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]):
Expand Down Expand Up @@ -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",
Expand All @@ -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")

Expand All @@ -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':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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:
Expand All @@ -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,
Expand All @@ -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],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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. "
Expand All @@ -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]
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -82,20 +82,20 @@ 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
if not all([elem is not None for elem in blender_shader_sockets]):
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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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],
Expand All @@ -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
Expand Down
Binary file modified tests/scenes/01_factors.blend
Binary file not shown.