glTF exporter: texture slots: code cleanup
This commit is contained in:
parent
e47d2bcfad
commit
2d8c1b2c61
|
@ -15,7 +15,7 @@
|
|||
bl_info = {
|
||||
'name': 'glTF 2.0 format',
|
||||
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
|
||||
"version": (1, 3, 22),
|
||||
"version": (1, 3, 23),
|
||||
'blender': (2, 90, 0),
|
||||
'location': 'File > Import-Export',
|
||||
'description': 'Import-Export as glTF 2.0',
|
||||
|
|
|
@ -29,18 +29,17 @@ from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extension
|
|||
|
||||
@cached
|
||||
def gather_image(
|
||||
blender_shader_sockets_or_texture_slots: typing.Union[typing.Tuple[bpy.types.NodeSocket],
|
||||
typing.Tuple[bpy.types.Texture]],
|
||||
blender_shader_sockets: typing.Tuple[bpy.types.NodeSocket],
|
||||
export_settings):
|
||||
if not __filter_image(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not __filter_image(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
image_data = __get_image_data(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
image_data = __get_image_data(blender_shader_sockets, export_settings)
|
||||
if image_data.empty():
|
||||
# The export image has no data
|
||||
return None
|
||||
|
||||
mime_type = __gather_mime_type(blender_shader_sockets_or_texture_slots, image_data, export_settings)
|
||||
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)
|
||||
|
@ -48,15 +47,15 @@ def gather_image(
|
|||
|
||||
image = __make_image(
|
||||
buffer_view,
|
||||
__gather_extensions(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
__gather_extras(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
__gather_extensions(blender_shader_sockets, export_settings),
|
||||
__gather_extras(blender_shader_sockets, export_settings),
|
||||
mime_type,
|
||||
name,
|
||||
uri,
|
||||
export_settings
|
||||
)
|
||||
|
||||
export_user_extensions('gather_image_hook', export_settings, image, blender_shader_sockets_or_texture_slots)
|
||||
export_user_extensions('gather_image_hook', export_settings, image, blender_shader_sockets)
|
||||
|
||||
return image
|
||||
|
||||
|
@ -72,8 +71,8 @@ def __make_image(buffer_view, extensions, extras, mime_type, name, uri, export_s
|
|||
)
|
||||
|
||||
|
||||
def __filter_image(sockets_or_slots, export_settings):
|
||||
if not sockets_or_slots:
|
||||
def __filter_image(sockets, export_settings):
|
||||
if not sockets:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -85,17 +84,17 @@ def __gather_buffer_view(image_data, mime_type, name, export_settings):
|
|||
return None
|
||||
|
||||
|
||||
def __gather_extensions(sockets_or_slots, export_settings):
|
||||
def __gather_extensions(sockets, export_settings):
|
||||
return None
|
||||
|
||||
|
||||
def __gather_extras(sockets_or_slots, export_settings):
|
||||
def __gather_extras(sockets, export_settings):
|
||||
return None
|
||||
|
||||
|
||||
def __gather_mime_type(sockets_or_slots, export_image, export_settings):
|
||||
def __gather_mime_type(sockets, export_image, export_settings):
|
||||
# force png if Alpha contained so we can export alpha
|
||||
for socket in sockets_or_slots:
|
||||
for socket in sockets:
|
||||
if socket.name == "Alpha":
|
||||
return "image/png"
|
||||
|
||||
|
@ -136,7 +135,6 @@ def __gather_name(export_image, export_settings):
|
|||
return name or 'Image'
|
||||
|
||||
|
||||
|
||||
@cached
|
||||
def __gather_uri(image_data, mime_type, name, export_settings):
|
||||
if export_settings[gltf2_blender_export_keys.FORMAT] == 'GLTF_SEPARATE':
|
||||
|
@ -150,77 +148,62 @@ def __gather_uri(image_data, mime_type, name, export_settings):
|
|||
return None
|
||||
|
||||
|
||||
def __is_socket(sockets_or_slots):
|
||||
return isinstance(sockets_or_slots[0], bpy.types.NodeSocket)
|
||||
|
||||
|
||||
def __is_slot(sockets_or_slots):
|
||||
return isinstance(sockets_or_slots[0], bpy.types.MaterialTextureSlot)
|
||||
|
||||
|
||||
def __get_image_data(sockets_or_slots, export_settings) -> ExportImage:
|
||||
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.
|
||||
if __is_socket(sockets_or_slots):
|
||||
results = [__get_tex_from_socket(socket, export_settings) for socket in sockets_or_slots]
|
||||
composed_image = ExportImage()
|
||||
for result, socket in zip(results, sockets_or_slots):
|
||||
if result.shader_node.image.channels == 0:
|
||||
gltf2_io_debug.print_console("WARNING",
|
||||
"Image '{}' has no color channels and cannot be exported.".format(
|
||||
result.shader_node.image))
|
||||
continue
|
||||
results = [__get_tex_from_socket(socket, export_settings) for socket in sockets]
|
||||
composed_image = ExportImage()
|
||||
for result, socket in zip(results, sockets):
|
||||
if result.shader_node.image.channels == 0:
|
||||
gltf2_io_debug.print_console("WARNING",
|
||||
"Image '{}' has no color channels and cannot be exported.".format(
|
||||
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
|
||||
# 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
|
||||
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' and len(sockets_or_slots) > 1 and sockets_or_slots[1] is not None:
|
||||
dst_chan = Channel.A
|
||||
elif socket.name == 'Clearcoat':
|
||||
dst_chan = Channel.R
|
||||
elif socket.name == 'Clearcoat Roughness':
|
||||
dst_chan = Channel.G
|
||||
# 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' and len(sockets) > 1 and sockets[1] is not None:
|
||||
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)
|
||||
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)
|
||||
# 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
|
||||
return composed_image
|
||||
|
||||
elif __is_slot(sockets_or_slots):
|
||||
texture = __get_tex_from_slot(sockets_or_slots[0])
|
||||
image = ExportImage.from_blender_image(texture.image)
|
||||
return image
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
|
||||
@cached
|
||||
def __get_tex_from_socket(blender_shader_socket: bpy.types.NodeSocket, export_settings):
|
||||
|
@ -232,10 +215,6 @@ def __get_tex_from_socket(blender_shader_socket: bpy.types.NodeSocket, export_se
|
|||
return result[0]
|
||||
|
||||
|
||||
def __get_tex_from_slot(blender_texture_slot):
|
||||
return blender_texture_slot.texture
|
||||
|
||||
|
||||
def __is_blender_image_a_jpeg(image: bpy.types.Image) -> bool:
|
||||
if image.source != 'FILE':
|
||||
return False
|
||||
|
|
|
@ -24,18 +24,18 @@ from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extension
|
|||
|
||||
|
||||
@cached
|
||||
def gather_material_normal_texture_info_class(blender_shader_sockets_or_texture_slots: typing.Union[
|
||||
typing.Tuple[bpy.types.NodeSocket], typing.Tuple[bpy.types.Texture]],
|
||||
def gather_material_normal_texture_info_class(
|
||||
blender_shader_sockets: typing.Tuple[bpy.types.NodeSocket],
|
||||
export_settings):
|
||||
if not __filter_texture_info(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not __filter_texture_info(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
texture_info = gltf2_io.MaterialNormalTextureInfoClass(
|
||||
extensions=__gather_extensions(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
extras=__gather_extras(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
scale=__gather_scale(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
index=__gather_index(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
tex_coord=__gather_tex_coord(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
extensions=__gather_extensions(blender_shader_sockets, export_settings),
|
||||
extras=__gather_extras(blender_shader_sockets, export_settings),
|
||||
scale=__gather_scale(blender_shader_sockets, export_settings),
|
||||
index=__gather_index(blender_shader_sockets, export_settings),
|
||||
tex_coord=__gather_tex_coord(blender_shader_sockets, export_settings)
|
||||
)
|
||||
|
||||
if texture_info.index is None:
|
||||
|
@ -44,28 +44,27 @@ def gather_material_normal_texture_info_class(blender_shader_sockets_or_texture_
|
|||
export_user_extensions('gather_material_normal_texture_info_class_hook',
|
||||
export_settings,
|
||||
texture_info,
|
||||
blender_shader_sockets_or_texture_slots)
|
||||
blender_shader_sockets)
|
||||
|
||||
return texture_info
|
||||
|
||||
|
||||
def __filter_texture_info(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not blender_shader_sockets_or_texture_slots:
|
||||
def __filter_texture_info(blender_shader_sockets, export_settings):
|
||||
if not blender_shader_sockets:
|
||||
return False
|
||||
if not all([elem is not None for elem in blender_shader_sockets_or_texture_slots]):
|
||||
if not all([elem is not None for elem in blender_shader_sockets]):
|
||||
return False
|
||||
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
|
||||
if isinstance(blender_shader_sockets_or_texture_slots[0], bpy.types.NodeSocket):
|
||||
if any([__get_tex_from_socket(socket) is None for socket in blender_shader_sockets_or_texture_slots]):
|
||||
# sockets do not lead to a texture --> discard
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def __gather_extensions(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not hasattr(blender_shader_sockets_or_texture_slots[0], 'links'):
|
||||
def __gather_extensions(blender_shader_sockets, export_settings):
|
||||
if not hasattr(blender_shader_sockets[0], 'links'):
|
||||
return None
|
||||
|
||||
tex_nodes = [__get_tex_from_socket(socket).shader_node for socket in blender_shader_sockets_or_texture_slots]
|
||||
tex_nodes = [__get_tex_from_socket(socket).shader_node for socket in blender_shader_sockets]
|
||||
texture_node = tex_nodes[0] if (tex_nodes is not None and len(tex_nodes) > 0) else None
|
||||
if texture_node is None:
|
||||
return None
|
||||
|
@ -77,62 +76,54 @@ def __gather_extensions(blender_shader_sockets_or_texture_slots, export_settings
|
|||
return {"KHR_texture_transform": extension}
|
||||
|
||||
|
||||
def __gather_extras(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
def __gather_extras(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
|
||||
def __gather_scale(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if __is_socket(blender_shader_sockets_or_texture_slots):
|
||||
result = gltf2_blender_search_node_tree.from_socket(
|
||||
blender_shader_sockets_or_texture_slots[0],
|
||||
gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeNormalMap))
|
||||
if not result:
|
||||
return None
|
||||
strengthInput = result[0].shader_node.inputs['Strength']
|
||||
if not strengthInput.is_linked and strengthInput.default_value != 1:
|
||||
return strengthInput.default_value
|
||||
def __gather_scale(blender_shader_sockets, export_settings):
|
||||
result = gltf2_blender_search_node_tree.from_socket(
|
||||
blender_shader_sockets[0],
|
||||
gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeNormalMap))
|
||||
if not result:
|
||||
return None
|
||||
strengthInput = result[0].shader_node.inputs['Strength']
|
||||
if not strengthInput.is_linked and strengthInput.default_value != 1:
|
||||
return strengthInput.default_value
|
||||
return None
|
||||
|
||||
|
||||
def __gather_index(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
def __gather_index(blender_shader_sockets, export_settings):
|
||||
# We just put the actual shader into the 'index' member
|
||||
return gltf2_blender_gather_texture.gather_texture(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
return gltf2_blender_gather_texture.gather_texture(blender_shader_sockets, export_settings)
|
||||
|
||||
|
||||
def __gather_tex_coord(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if __is_socket(blender_shader_sockets_or_texture_slots):
|
||||
blender_shader_node = __get_tex_from_socket(blender_shader_sockets_or_texture_slots[0]).shader_node
|
||||
if len(blender_shader_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = blender_shader_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if isinstance(input_node, bpy.types.ShaderNodeMapping):
|
||||
|
||||
if len(input_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = input_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if not isinstance(input_node, bpy.types.ShaderNodeUVMap):
|
||||
return 0
|
||||
|
||||
if input_node.uv_map == '':
|
||||
return 0
|
||||
|
||||
# Try to gather map index.
|
||||
for blender_mesh in bpy.data.meshes:
|
||||
texCoordIndex = blender_mesh.uv_layers.find(input_node.uv_map)
|
||||
if texCoordIndex >= 0:
|
||||
return texCoordIndex
|
||||
|
||||
def __gather_tex_coord(blender_shader_sockets, export_settings):
|
||||
blender_shader_node = __get_tex_from_socket(blender_shader_sockets[0]).shader_node
|
||||
if len(blender_shader_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
|
||||
input_node = blender_shader_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
def __is_socket(sockets_or_slots):
|
||||
return isinstance(sockets_or_slots[0], bpy.types.NodeSocket)
|
||||
if isinstance(input_node, bpy.types.ShaderNodeMapping):
|
||||
|
||||
if len(input_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = input_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if not isinstance(input_node, bpy.types.ShaderNodeUVMap):
|
||||
return 0
|
||||
|
||||
if input_node.uv_map == '':
|
||||
return 0
|
||||
|
||||
# Try to gather map index.
|
||||
for blender_mesh in bpy.data.meshes:
|
||||
texCoordIndex = blender_mesh.uv_layers.find(input_node.uv_map)
|
||||
if texCoordIndex >= 0:
|
||||
return texCoordIndex
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def __get_tex_from_socket(socket):
|
||||
|
|
|
@ -24,18 +24,18 @@ from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extension
|
|||
|
||||
|
||||
@cached
|
||||
def gather_material_occlusion_texture_info_class(blender_shader_sockets_or_texture_slots: typing.Union[
|
||||
typing.Tuple[bpy.types.NodeSocket], typing.Tuple[bpy.types.Texture]],
|
||||
def gather_material_occlusion_texture_info_class(
|
||||
blender_shader_sockets: typing.Tuple[bpy.types.NodeSocket],
|
||||
export_settings):
|
||||
if not __filter_texture_info(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not __filter_texture_info(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
texture_info = gltf2_io.MaterialOcclusionTextureInfoClass(
|
||||
extensions=__gather_extensions(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
extras=__gather_extras(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
strength=__gather_scale(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
index=__gather_index(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
tex_coord=__gather_tex_coord(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
extensions=__gather_extensions(blender_shader_sockets, export_settings),
|
||||
extras=__gather_extras(blender_shader_sockets, export_settings),
|
||||
strength=__gather_scale(blender_shader_sockets, export_settings),
|
||||
index=__gather_index(blender_shader_sockets, export_settings),
|
||||
tex_coord=__gather_tex_coord(blender_shader_sockets, export_settings)
|
||||
)
|
||||
|
||||
if texture_info.index is None:
|
||||
|
@ -44,28 +44,27 @@ def gather_material_occlusion_texture_info_class(blender_shader_sockets_or_textu
|
|||
export_user_extensions('gather_material_occlusion_texture_info_class_hook',
|
||||
export_settings,
|
||||
texture_info,
|
||||
blender_shader_sockets_or_texture_slots)
|
||||
blender_shader_sockets)
|
||||
|
||||
return texture_info
|
||||
|
||||
|
||||
def __filter_texture_info(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not blender_shader_sockets_or_texture_slots:
|
||||
def __filter_texture_info(blender_shader_sockets, export_settings):
|
||||
if not blender_shader_sockets:
|
||||
return False
|
||||
if not all([elem is not None for elem in blender_shader_sockets_or_texture_slots]):
|
||||
if not all([elem is not None for elem in blender_shader_sockets]):
|
||||
return False
|
||||
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
|
||||
if isinstance(blender_shader_sockets_or_texture_slots[0], bpy.types.NodeSocket):
|
||||
if any([__get_tex_from_socket(socket) is None for socket in blender_shader_sockets_or_texture_slots]):
|
||||
# sockets do not lead to a texture --> discard
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def __gather_extensions(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not hasattr(blender_shader_sockets_or_texture_slots[0], 'links'):
|
||||
def __gather_extensions(blender_shader_sockets, export_settings):
|
||||
if not hasattr(blender_shader_sockets[0], 'links'):
|
||||
return None
|
||||
|
||||
tex_nodes = [__get_tex_from_socket(socket).shader_node for socket in blender_shader_sockets_or_texture_slots]
|
||||
tex_nodes = [__get_tex_from_socket(socket).shader_node for socket in blender_shader_sockets]
|
||||
texture_node = tex_nodes[0] if (tex_nodes is not None and len(tex_nodes) > 0) else None
|
||||
if texture_node is None:
|
||||
return None
|
||||
|
@ -77,53 +76,46 @@ def __gather_extensions(blender_shader_sockets_or_texture_slots, export_settings
|
|||
return {"KHR_texture_transform": extension}
|
||||
|
||||
|
||||
def __gather_extras(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
def __gather_extras(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
|
||||
def __gather_scale(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
def __gather_scale(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
|
||||
def __gather_index(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
def __gather_index(blender_shader_sockets, export_settings):
|
||||
# We just put the actual shader into the 'index' member
|
||||
return gltf2_blender_gather_texture.gather_texture(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
return gltf2_blender_gather_texture.gather_texture(blender_shader_sockets, export_settings)
|
||||
|
||||
|
||||
def __gather_tex_coord(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if __is_socket(blender_shader_sockets_or_texture_slots):
|
||||
blender_shader_node = __get_tex_from_socket(blender_shader_sockets_or_texture_slots[0]).shader_node
|
||||
if len(blender_shader_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = blender_shader_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if isinstance(input_node, bpy.types.ShaderNodeMapping):
|
||||
|
||||
if len(input_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = input_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if not isinstance(input_node, bpy.types.ShaderNodeUVMap):
|
||||
return 0
|
||||
|
||||
if input_node.uv_map == '':
|
||||
return 0
|
||||
|
||||
# Try to gather map index.
|
||||
for blender_mesh in bpy.data.meshes:
|
||||
texCoordIndex = blender_mesh.uv_layers.find(input_node.uv_map)
|
||||
if texCoordIndex >= 0:
|
||||
return texCoordIndex
|
||||
|
||||
def __gather_tex_coord(blender_shader_sockets, export_settings):
|
||||
blender_shader_node = __get_tex_from_socket(blender_shader_sockets[0]).shader_node
|
||||
if len(blender_shader_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
|
||||
input_node = blender_shader_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
def __is_socket(sockets_or_slots):
|
||||
return isinstance(sockets_or_slots[0], bpy.types.NodeSocket)
|
||||
if isinstance(input_node, bpy.types.ShaderNodeMapping):
|
||||
|
||||
if len(input_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = input_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if not isinstance(input_node, bpy.types.ShaderNodeUVMap):
|
||||
return 0
|
||||
|
||||
if input_node.uv_map == '':
|
||||
return 0
|
||||
|
||||
# Try to gather map index.
|
||||
for blender_mesh in bpy.data.meshes:
|
||||
texCoordIndex = blender_mesh.uv_layers.find(input_node.uv_map)
|
||||
if texCoordIndex >= 0:
|
||||
return texCoordIndex
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def __get_tex_from_socket(socket):
|
||||
|
|
|
@ -98,7 +98,7 @@ def __gather_double_sided(blender_material, mesh_double_sided, export_settings):
|
|||
if mesh_double_sided:
|
||||
return True
|
||||
|
||||
old_double_sided_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "DoubleSided")
|
||||
old_double_sided_socket = gltf2_blender_get.get_socket_old(blender_material, "DoubleSided")
|
||||
if old_double_sided_socket is not None and\
|
||||
not old_double_sided_socket.is_linked and\
|
||||
old_double_sided_socket.default_value > 0.5:
|
||||
|
@ -107,9 +107,9 @@ def __gather_double_sided(blender_material, mesh_double_sided, export_settings):
|
|||
|
||||
|
||||
def __gather_emissive_factor(blender_material, export_settings):
|
||||
emissive_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Emissive")
|
||||
emissive_socket = gltf2_blender_get.get_socket(blender_material, "Emissive")
|
||||
if emissive_socket is None:
|
||||
emissive_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "EmissiveFactor")
|
||||
emissive_socket = gltf2_blender_get.get_socket_old(blender_material, "EmissiveFactor")
|
||||
if isinstance(emissive_socket, bpy.types.NodeSocket):
|
||||
if emissive_socket.is_linked:
|
||||
# In glTF, the default emissiveFactor is all zeros, so if an emission texture is connected,
|
||||
|
@ -121,9 +121,9 @@ def __gather_emissive_factor(blender_material, export_settings):
|
|||
|
||||
|
||||
def __gather_emissive_texture(blender_material, export_settings):
|
||||
emissive = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Emissive")
|
||||
emissive = gltf2_blender_get.get_socket(blender_material, "Emissive")
|
||||
if emissive is None:
|
||||
emissive = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Emissive")
|
||||
emissive = gltf2_blender_get.get_socket_old(blender_material, "Emissive")
|
||||
return gltf2_blender_gather_texture_info.gather_texture_info((emissive,), export_settings)
|
||||
|
||||
|
||||
|
@ -132,7 +132,7 @@ def __gather_extensions(blender_material, export_settings):
|
|||
|
||||
# KHR_materials_unlit
|
||||
|
||||
if gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Background") is not None:
|
||||
if gltf2_blender_get.get_socket(blender_material, "Background") is not None:
|
||||
extensions["KHR_materials_unlit"] = Extension("KHR_materials_unlit", {}, False)
|
||||
|
||||
# KHR_materials_clearcoat
|
||||
|
@ -157,9 +157,9 @@ def __gather_name(blender_material, export_settings):
|
|||
|
||||
|
||||
def __gather_normal_texture(blender_material, export_settings):
|
||||
normal = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Normal")
|
||||
normal = gltf2_blender_get.get_socket(blender_material, "Normal")
|
||||
if normal is None:
|
||||
normal = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Normal")
|
||||
normal = gltf2_blender_get.get_socket_old(blender_material, "Normal")
|
||||
return gltf2_blender_gather_material_normal_texture_info_class.gather_material_normal_texture_info_class(
|
||||
(normal,),
|
||||
export_settings)
|
||||
|
@ -169,20 +169,20 @@ def __gather_orm_texture(blender_material, export_settings):
|
|||
# Check for the presence of Occlusion, Roughness, Metallic sharing a single image.
|
||||
# If not fully shared, return None, so the images will be cached and processed separately.
|
||||
|
||||
occlusion = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Occlusion")
|
||||
occlusion = gltf2_blender_get.get_socket(blender_material, "Occlusion")
|
||||
if occlusion is None or not __has_image_node_from_socket(occlusion):
|
||||
occlusion = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Occlusion")
|
||||
occlusion = gltf2_blender_get.get_socket_old(blender_material, "Occlusion")
|
||||
if occlusion is None or not __has_image_node_from_socket(occlusion):
|
||||
return None
|
||||
|
||||
metallic_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Metallic")
|
||||
roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Roughness")
|
||||
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)
|
||||
|
||||
if not hasMetal and not hasRough:
|
||||
metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "MetallicRoughness")
|
||||
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):
|
||||
return None
|
||||
result = (occlusion, metallic_roughness)
|
||||
|
@ -211,9 +211,9 @@ def __gather_occlusion_texture(blender_material, orm_texture, export_settings):
|
|||
return gltf2_blender_gather_material_occlusion_texture_info_class.gather_material_occlusion_texture_info_class(
|
||||
orm_texture,
|
||||
export_settings)
|
||||
occlusion = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Occlusion")
|
||||
occlusion = gltf2_blender_get.get_socket(blender_material, "Occlusion")
|
||||
if occlusion is None:
|
||||
occlusion = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "Occlusion")
|
||||
occlusion = gltf2_blender_get.get_socket_old(blender_material, "Occlusion")
|
||||
return gltf2_blender_gather_material_occlusion_texture_info_class.gather_material_occlusion_texture_info_class(
|
||||
(occlusion,),
|
||||
export_settings)
|
||||
|
@ -241,9 +241,9 @@ def __gather_clearcoat_extension(blender_material, export_settings):
|
|||
clearcoat_extension = {}
|
||||
clearcoat_roughness_slots = ()
|
||||
|
||||
clearcoat_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, 'Clearcoat')
|
||||
clearcoat_roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, 'Clearcoat Roughness')
|
||||
clearcoat_normal_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, 'Clearcoat Normal')
|
||||
clearcoat_socket = gltf2_blender_get.get_socket(blender_material, 'Clearcoat')
|
||||
clearcoat_roughness_socket = gltf2_blender_get.get_socket(blender_material, 'Clearcoat Roughness')
|
||||
clearcoat_normal_socket = gltf2_blender_get.get_socket(blender_material, 'Clearcoat Normal')
|
||||
|
||||
if isinstance(clearcoat_socket, bpy.types.NodeSocket) and not clearcoat_socket.is_linked:
|
||||
clearcoat_extension['clearcoatFactor'] = clearcoat_socket.default_value
|
||||
|
|
|
@ -47,13 +47,13 @@ def __filter_pbr_material(blender_material, export_settings):
|
|||
|
||||
|
||||
def __gather_base_color_factor(blender_material, export_settings):
|
||||
base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Base Color")
|
||||
base_color_socket = gltf2_blender_get.get_socket(blender_material, "Base Color")
|
||||
if base_color_socket is None:
|
||||
base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "BaseColor")
|
||||
base_color_socket = gltf2_blender_get.get_socket(blender_material, "BaseColor")
|
||||
if base_color_socket is None:
|
||||
base_color_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "BaseColorFactor")
|
||||
base_color_socket = gltf2_blender_get.get_socket_old(blender_material, "BaseColorFactor")
|
||||
if base_color_socket is None:
|
||||
base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Background")
|
||||
base_color_socket = gltf2_blender_get.get_socket(blender_material, "Background")
|
||||
if not isinstance(base_color_socket, bpy.types.NodeSocket):
|
||||
return None
|
||||
if not base_color_socket.is_linked:
|
||||
|
@ -89,15 +89,15 @@ def __gather_base_color_factor(blender_material, export_settings):
|
|||
|
||||
|
||||
def __gather_base_color_texture(blender_material, export_settings):
|
||||
base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Base Color")
|
||||
base_color_socket = gltf2_blender_get.get_socket(blender_material, "Base Color")
|
||||
if base_color_socket is None:
|
||||
base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "BaseColor")
|
||||
base_color_socket = gltf2_blender_get.get_socket(blender_material, "BaseColor")
|
||||
if base_color_socket is None:
|
||||
base_color_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "BaseColor")
|
||||
base_color_socket = gltf2_blender_get.get_socket_old(blender_material, "BaseColor")
|
||||
if base_color_socket is None:
|
||||
base_color_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Background")
|
||||
base_color_socket = gltf2_blender_get.get_socket(blender_material, "Background")
|
||||
|
||||
alpha_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Alpha")
|
||||
alpha_socket = gltf2_blender_get.get_socket(blender_material, "Alpha")
|
||||
if alpha_socket is not None and alpha_socket.is_linked:
|
||||
inputs = (base_color_socket, alpha_socket, )
|
||||
else:
|
||||
|
@ -124,9 +124,9 @@ def __gather_extras(blender_material, export_settings):
|
|||
|
||||
|
||||
def __gather_metallic_factor(blender_material, export_settings):
|
||||
metallic_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Metallic")
|
||||
metallic_socket = gltf2_blender_get.get_socket(blender_material, "Metallic")
|
||||
if metallic_socket is None:
|
||||
metallic_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "MetallicFactor")
|
||||
metallic_socket = gltf2_blender_get.get_socket_old(blender_material, "MetallicFactor")
|
||||
if isinstance(metallic_socket, bpy.types.NodeSocket) and not metallic_socket.is_linked:
|
||||
return metallic_socket.default_value
|
||||
return None
|
||||
|
@ -136,14 +136,14 @@ def __gather_metallic_roughness_texture(blender_material, orm_texture, export_se
|
|||
if orm_texture is not None:
|
||||
texture_input = orm_texture
|
||||
else:
|
||||
metallic_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Metallic")
|
||||
roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Roughness")
|
||||
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)
|
||||
|
||||
if not hasMetal and not hasRough:
|
||||
metallic_roughness = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "MetallicRoughness")
|
||||
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):
|
||||
return None
|
||||
texture_input = (metallic_roughness,)
|
||||
|
@ -158,9 +158,9 @@ def __gather_metallic_roughness_texture(blender_material, orm_texture, export_se
|
|||
|
||||
|
||||
def __gather_roughness_factor(blender_material, export_settings):
|
||||
roughness_socket = gltf2_blender_get.get_socket_or_texture_slot(blender_material, "Roughness")
|
||||
roughness_socket = gltf2_blender_get.get_socket(blender_material, "Roughness")
|
||||
if roughness_socket is None:
|
||||
roughness_socket = gltf2_blender_get.get_socket_or_texture_slot_old(blender_material, "RoughnessFactor")
|
||||
roughness_socket = gltf2_blender_get.get_socket_old(blender_material, "RoughnessFactor")
|
||||
if isinstance(roughness_socket, bpy.types.NodeSocket) and not roughness_socket.is_linked:
|
||||
return roughness_socket.default_value
|
||||
return None
|
||||
|
|
|
@ -78,25 +78,3 @@ def __gather_wrap_t(blender_shader_node, export_settings):
|
|||
if blender_shader_node.extension == 'EXTEND':
|
||||
return 33071
|
||||
return None
|
||||
|
||||
|
||||
@cached
|
||||
def gather_sampler_from_texture_slot(blender_texture: bpy.types.TextureSlot, export_settings):
|
||||
magFilter = 9729
|
||||
wrap = 10497
|
||||
if blender_texture.texture.extension == 'EXTEND':
|
||||
wrap = 33071
|
||||
|
||||
minFilter = 9986
|
||||
if magFilter == 9728:
|
||||
minFilter = 9984
|
||||
|
||||
return gltf2_io.Sampler(
|
||||
extensions=None,
|
||||
extras=None,
|
||||
mag_filter=magFilter,
|
||||
min_filter=minFilter,
|
||||
name=None,
|
||||
wrap_s=wrap,
|
||||
wrap_t=wrap
|
||||
)
|
||||
|
|
|
@ -26,8 +26,7 @@ from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extension
|
|||
|
||||
@cached
|
||||
def gather_texture(
|
||||
blender_shader_sockets_or_texture_slots: typing.Union[
|
||||
typing.Tuple[bpy.types.NodeSocket], typing.Tuple[typing.Any]],
|
||||
blender_shader_sockets: typing.Tuple[bpy.types.NodeSocket],
|
||||
export_settings):
|
||||
"""
|
||||
Gather texture sampling information and image channels from a blender shader texture attached to a shader socket.
|
||||
|
@ -36,28 +35,27 @@ def gather_texture(
|
|||
:param export_settings: configuration of the export
|
||||
:return: a glTF 2.0 texture with sampler and source embedded (will be converted to references by the exporter)
|
||||
"""
|
||||
# TODO: extend to texture slots
|
||||
if not __filter_texture(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not __filter_texture(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
texture = gltf2_io.Texture(
|
||||
extensions=__gather_extensions(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
extras=__gather_extras(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
name=__gather_name(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
sampler=__gather_sampler(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
source=__gather_source(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
extensions=__gather_extensions(blender_shader_sockets, export_settings),
|
||||
extras=__gather_extras(blender_shader_sockets, export_settings),
|
||||
name=__gather_name(blender_shader_sockets, export_settings),
|
||||
sampler=__gather_sampler(blender_shader_sockets, export_settings),
|
||||
source=__gather_source(blender_shader_sockets, export_settings)
|
||||
)
|
||||
|
||||
# although valid, most viewers can't handle missing source properties
|
||||
if texture.source is None:
|
||||
return None
|
||||
|
||||
export_user_extensions('gather_texture_hook', export_settings, texture, blender_shader_sockets_or_texture_slots)
|
||||
export_user_extensions('gather_texture_hook', export_settings, texture, blender_shader_sockets)
|
||||
|
||||
return texture
|
||||
|
||||
|
||||
def __filter_texture(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
def __filter_texture(blender_shader_sockets, export_settings):
|
||||
return True
|
||||
|
||||
|
||||
|
@ -73,28 +71,19 @@ def __gather_name(blender_shader_sockets, export_settings):
|
|||
return None
|
||||
|
||||
|
||||
def __gather_sampler(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if isinstance(blender_shader_sockets_or_texture_slots[0], bpy.types.NodeSocket):
|
||||
shader_nodes = [__get_tex_from_socket(socket).shader_node for socket in blender_shader_sockets_or_texture_slots]
|
||||
if len(shader_nodes) > 1:
|
||||
gltf2_io_debug.print_console("WARNING",
|
||||
"More than one shader node tex image used for a texture. "
|
||||
"The resulting glTF sampler will behave like the first shader node tex image.")
|
||||
return gltf2_blender_gather_sampler.gather_sampler(
|
||||
shader_nodes[0],
|
||||
export_settings)
|
||||
elif isinstance(blender_shader_sockets_or_texture_slots[0], bpy.types.MaterialTextureSlot):
|
||||
return gltf2_blender_gather_sampler.gather_sampler_from_texture_slot(
|
||||
blender_shader_sockets_or_texture_slots[0],
|
||||
export_settings
|
||||
)
|
||||
else:
|
||||
# TODO: implement texture slot sampler
|
||||
raise NotImplementedError()
|
||||
def __gather_sampler(blender_shader_sockets, export_settings):
|
||||
shader_nodes = [__get_tex_from_socket(socket).shader_node 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. "
|
||||
"The resulting glTF sampler will behave like the first shader node tex image.")
|
||||
return gltf2_blender_gather_sampler.gather_sampler(
|
||||
shader_nodes[0],
|
||||
export_settings)
|
||||
|
||||
|
||||
def __gather_source(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
return gltf2_blender_gather_image.gather_image(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
def __gather_source(blender_shader_sockets, export_settings):
|
||||
return gltf2_blender_gather_image.gather_image(blender_shader_sockets, export_settings)
|
||||
|
||||
# Helpers
|
||||
|
||||
|
|
|
@ -24,45 +24,44 @@ from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extension
|
|||
|
||||
|
||||
@cached
|
||||
def gather_texture_info(blender_shader_sockets_or_texture_slots: typing.Union[
|
||||
typing.Tuple[bpy.types.NodeSocket], typing.Tuple[bpy.types.Texture]],
|
||||
def gather_texture_info(
|
||||
blender_shader_sockets: typing.Tuple[bpy.types.NodeSocket],
|
||||
export_settings):
|
||||
if not __filter_texture_info(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not __filter_texture_info(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
texture_info = gltf2_io.TextureInfo(
|
||||
extensions=__gather_extensions(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
extras=__gather_extras(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
index=__gather_index(blender_shader_sockets_or_texture_slots, export_settings),
|
||||
tex_coord=__gather_tex_coord(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
extensions=__gather_extensions(blender_shader_sockets, export_settings),
|
||||
extras=__gather_extras(blender_shader_sockets, export_settings),
|
||||
index=__gather_index(blender_shader_sockets, export_settings),
|
||||
tex_coord=__gather_tex_coord(blender_shader_sockets, export_settings)
|
||||
)
|
||||
|
||||
if texture_info.index is None:
|
||||
return None
|
||||
|
||||
export_user_extensions('gather_texture_info_hook', export_settings, texture_info, blender_shader_sockets_or_texture_slots)
|
||||
export_user_extensions('gather_texture_info_hook', export_settings, texture_info, blender_shader_sockets)
|
||||
|
||||
return texture_info
|
||||
|
||||
|
||||
def __filter_texture_info(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not blender_shader_sockets_or_texture_slots:
|
||||
def __filter_texture_info(blender_shader_sockets, export_settings):
|
||||
if not blender_shader_sockets:
|
||||
return False
|
||||
if not all([elem is not None for elem in blender_shader_sockets_or_texture_slots]):
|
||||
if not all([elem is not None for elem in blender_shader_sockets]):
|
||||
return False
|
||||
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
|
||||
if isinstance(blender_shader_sockets_or_texture_slots[0], bpy.types.NodeSocket):
|
||||
if any([__get_tex_from_socket(socket) is None for socket in blender_shader_sockets_or_texture_slots]):
|
||||
# sockets do not lead to a texture --> discard
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def __gather_extensions(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if not hasattr(blender_shader_sockets_or_texture_slots[0], 'links'):
|
||||
def __gather_extensions(blender_shader_sockets, export_settings):
|
||||
if not hasattr(blender_shader_sockets[0], 'links'):
|
||||
return None
|
||||
|
||||
tex_nodes = [__get_tex_from_socket(socket).shader_node for socket in blender_shader_sockets_or_texture_slots]
|
||||
tex_nodes = [__get_tex_from_socket(socket).shader_node for socket in blender_shader_sockets]
|
||||
texture_node = tex_nodes[0] if (tex_nodes is not None and len(tex_nodes) > 0) else None
|
||||
if texture_node is None:
|
||||
return None
|
||||
|
@ -74,48 +73,42 @@ def __gather_extensions(blender_shader_sockets_or_texture_slots, export_settings
|
|||
return {"KHR_texture_transform": extension}
|
||||
|
||||
|
||||
def __gather_extras(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
def __gather_extras(blender_shader_sockets, export_settings):
|
||||
return None
|
||||
|
||||
|
||||
def __gather_index(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
def __gather_index(blender_shader_sockets, export_settings):
|
||||
# We just put the actual shader into the 'index' member
|
||||
return gltf2_blender_gather_texture.gather_texture(blender_shader_sockets_or_texture_slots, export_settings)
|
||||
return gltf2_blender_gather_texture.gather_texture(blender_shader_sockets, export_settings)
|
||||
|
||||
|
||||
def __gather_tex_coord(blender_shader_sockets_or_texture_slots, export_settings):
|
||||
if isinstance(blender_shader_sockets_or_texture_slots[0], bpy.types.NodeSocket):
|
||||
blender_shader_node = __get_tex_from_socket(blender_shader_sockets_or_texture_slots[0]).shader_node
|
||||
if len(blender_shader_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = blender_shader_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if isinstance(input_node, bpy.types.ShaderNodeMapping):
|
||||
|
||||
if len(input_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = input_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if not isinstance(input_node, bpy.types.ShaderNodeUVMap):
|
||||
return 0
|
||||
|
||||
if input_node.uv_map == '':
|
||||
return 0
|
||||
|
||||
# Try to gather map index.
|
||||
for blender_mesh in bpy.data.meshes:
|
||||
texCoordIndex = blender_mesh.uv_layers.find(input_node.uv_map)
|
||||
if texCoordIndex >= 0:
|
||||
return texCoordIndex
|
||||
|
||||
def __gather_tex_coord(blender_shader_sockets, export_settings):
|
||||
blender_shader_node = __get_tex_from_socket(blender_shader_sockets[0]).shader_node
|
||||
if len(blender_shader_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
elif isinstance(blender_shader_sockets_or_texture_slots[0], bpy.types.MaterialTextureSlot):
|
||||
# TODO: implement for texture slots
|
||||
|
||||
input_node = blender_shader_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if isinstance(input_node, bpy.types.ShaderNodeMapping):
|
||||
|
||||
if len(input_node.inputs['Vector'].links) == 0:
|
||||
return 0
|
||||
|
||||
input_node = input_node.inputs['Vector'].links[0].from_node
|
||||
|
||||
if not isinstance(input_node, bpy.types.ShaderNodeUVMap):
|
||||
return 0
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
|
||||
if input_node.uv_map == '':
|
||||
return 0
|
||||
|
||||
# Try to gather map index.
|
||||
for blender_mesh in bpy.data.meshes:
|
||||
texCoordIndex = blender_mesh.uv_layers.find(input_node.uv_map)
|
||||
if texCoordIndex >= 0:
|
||||
return texCoordIndex
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def __get_tex_from_socket(socket):
|
||||
|
|
|
@ -43,13 +43,13 @@ def get_object_from_datapath(blender_object, data_path: str):
|
|||
return prop
|
||||
|
||||
|
||||
def get_socket_or_texture_slot(blender_material: bpy.types.Material, name: str):
|
||||
def get_socket(blender_material: bpy.types.Material, name: str):
|
||||
"""
|
||||
For a given material input name, retrieve the corresponding node tree socket or blender render texture slot.
|
||||
For a given material input name, retrieve the corresponding node tree socket.
|
||||
|
||||
:param blender_material: a blender material for which to get the socket/slot
|
||||
:param name: the name of the socket/slot
|
||||
:return: either a blender NodeSocket, if the material is a node tree or a blender Texture otherwise
|
||||
:param blender_material: a blender material for which to get the socket
|
||||
:param name: the name of the socket
|
||||
:return: a blender NodeSocket
|
||||
"""
|
||||
if blender_material.node_tree and blender_material.use_nodes:
|
||||
#i = [input for input in blender_material.node_tree.inputs]
|
||||
|
@ -79,13 +79,13 @@ def get_socket_or_texture_slot(blender_material: bpy.types.Material, name: str):
|
|||
return None
|
||||
|
||||
|
||||
def get_socket_or_texture_slot_old(blender_material: bpy.types.Material, name: str):
|
||||
def get_socket_old(blender_material: bpy.types.Material, name: str):
|
||||
"""
|
||||
For a given material input name, retrieve the corresponding node tree socket in the special glTF node group.
|
||||
|
||||
:param blender_material: a blender material for which to get the socket/slot
|
||||
:param name: the name of the socket/slot
|
||||
:return: either a blender NodeSocket, if the material is a node tree or a blender Texture otherwise
|
||||
:param blender_material: a blender material for which to get the socket
|
||||
:param name: the name of the socket
|
||||
:return: a blender NodeSocket
|
||||
"""
|
||||
gltf_node_group_name = get_gltf_node_name().lower()
|
||||
if blender_material.node_tree and blender_material.use_nodes:
|
||||
|
|
Loading…
Reference in New Issue