Export ImageTexture node for an image identified in material node tree #39
114
source/material_node_search.py
Normal file
114
source/material_node_search.py
Normal file
@ -0,0 +1,114 @@
|
||||
# SPDX-FileCopyrightText: 2011-2024 Blender Foundation
|
||||
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import logging
|
||||
_logger = logging.getLogger("export_x3d.material_node_search")
|
||||
|
||||
"""
|
||||
functions implementing searching the node tree for Blender materials in search
|
||||
of particular nodes enabling export of material properties into other formats
|
||||
"""
|
||||
|
||||
|
||||
# node based material identifiers
|
||||
#BSDF_PRINCIPLED = 'BSDF_PRINCIPLED'
|
||||
|
||||
# IMAGE = 'image'
|
||||
|
||||
# values of bl_idname for shader nodes to be located
|
||||
# reference Python API list of subclasses of ShaderNode
|
||||
# at https://docs.blender.org/api/current/bpy.types.ShaderNode.html#bpy.types.ShaderNode
|
||||
class _ShaderNodeTypes:
|
||||
MATERIAL_OUTPUT= "ShaderNodeOutputMaterial"
|
||||
BSDF_PRINCIPLED = "ShaderNodeBsdfPrincipled"
|
||||
IMAGE_TEXTURE = "ShaderNodeTexImage"
|
||||
|
||||
# supported values of Image Texture Node extension property
|
||||
# REPEAT="REPEAT"
|
||||
# CLIP ="CLIP"
|
||||
|
||||
def _find_node_by_idname(nodes, idname):
|
||||
"""
|
||||
nodes a sequence of Nodes, idname a string
|
||||
Cedric Steiert
commented
a few typos here a few typos here
|
||||
Each node assumed to ne an instance of Node(bpy_struct)
|
||||
https://docs.blender.org/api/current/bpy.types.Node.html
|
||||
|
||||
The idname is searched for in the Node instance member bl_idname
|
||||
https://docs.blender.org/api/current/bpy.types.Node.html#bpy.types.Node.bl_idname
|
||||
and is generally some string version of the name of the subclass
|
||||
|
||||
See https://docs.blender.org/api/current/bpy.types.ShaderNode.html for list of
|
||||
ShaderNode subclasses
|
||||
|
||||
if 0 targets are found, returns None
|
||||
Cedric Steiert
commented
the output as code is not really needed in the docstring, but if you want simplify: Returns None if no targets are found or returns the first found target the output as code is not really needed in the docstring, but if you want simplify: Returns None if no targets are found or returns the first found target
|
||||
if 1 target is found returns that Node
|
||||
if more than 1 targets are found prints warning string and returns first found
|
||||
"""
|
||||
_logger.debug("enter _find_node_by_idname search for %s in %r" % (idname, nodes))
|
||||
nodelist = [nd for nd in nodes if nd.bl_idname == idname]
|
||||
_logger.debug("result _find_node_by_idname found %i" % len(nodelist))
|
||||
if len(nodelist) == 0:
|
||||
return None
|
||||
if len(nodelist) > 1:
|
||||
_logger.warn("_find_node_by_idname : multiple (%i) nodes of type %s found" % (len(nodelist), idname))
|
||||
return nodelist[0]
|
||||
|
||||
def imageTexture_in_material(material):
|
||||
"""
|
||||
argument material an instance of Material(ID)
|
||||
https://docs.blender.org/api/current/bpy.types.Material.html
|
||||
|
||||
returns instance of ShaderNodeTexImage
|
||||
https://docs.blender.org/api/current/bpy.types.ShaderNodeTexImage.html
|
||||
"""
|
||||
_logger.debug("evaluating image in material %s" % material.name)
|
||||
|
||||
material_output = _find_node_by_idname( material.node_tree.nodes, _ShaderNodeTypes.MATERIAL_OUTPUT)
|
||||
if material_output is None:
|
||||
_logger.warn("%s not found in material %s" % (_ShaderNodeTypes.MATERIAL_OUTPUT, material.name))
|
||||
return None
|
||||
|
||||
SURFACE_ATTRIBUTE= "Surface"
|
||||
bsdf_principled = _find_node_by_idname(
|
||||
[ndlink.from_node for ndlink in material_output.inputs.get(SURFACE_ATTRIBUTE).links],
|
||||
_ShaderNodeTypes.BSDF_PRINCIPLED)
|
||||
if bsdf_principled is None : return None
|
||||
Cedric Steiert
commented
for better readability put the return into it's own line for better readability put the return into it's own line
|
||||
|
||||
BASE_COLOR_ATTRIBUTE = 'Base Color'
|
||||
image_texture = _find_node_by_idname(
|
||||
[ndlink.from_node for ndlink in bsdf_principled.inputs.get(BASE_COLOR_ATTRIBUTE).links],
|
||||
_ShaderNodeTypes.IMAGE_TEXTURE )
|
||||
if image_texture is None: return None
|
||||
Cedric Steiert
commented
for better readability put the return into it's own line for better readability put the return into it's own line
|
||||
_logger.debug("located image texture node %r" % image_texture)
|
||||
return image_texture
|
||||
|
||||
## x3d_supported_file_extension = {"PNG" : ".png","JPEG" : ".jpg"}
|
||||
Cedric Steiert
commented
dead code dead code
|
||||
## if image_texture.image.file_format not in x3d_supported_file_extension:
|
||||
## logger.warn("images of format %s not supported" % image_texture.image.file_format)
|
||||
## return None
|
||||
##
|
||||
## retVal = self.ImageExportRecord()
|
||||
## retVal.image = image_texture.image
|
||||
##
|
||||
## # ref https://docs.blender.org/api/current/bpy.types.ShaderNodeTexImage.html#bpy.types.ShaderNodeTexImage.extension
|
||||
## x3d_supported_extension = [CLIP, REPEAT]
|
||||
## if image_texture.extension in x3d_supported_extension:
|
||||
## retVal.extension = image_texture.extension
|
||||
## else:
|
||||
## logger.warn("image_texture.extension value %s unsupported in X3D" % image_texture.extension)
|
||||
## retVal.extension=REPEAT
|
||||
##
|
||||
## packed_file = image_texture.image.packed_file
|
||||
## if packed_file is not None and packed_file.size > 0:
|
||||
## from os.path import splitext, basename
|
||||
## name_base = splitext( basename(image_texture.image.name))[0]
|
||||
## url_ext = x3d_supported_file_extension[image_texture.image.file_format]
|
||||
## retVal.url = name_base +url_ext
|
||||
##
|
||||
## logger.info("ImageExportRecord : %s packed: %r url: %s : extension: %r" % \
|
||||
## (retVal.image.name, retVal.is_packed,
|
||||
## retVal.url , retVal.extension))
|
||||
##
|
||||
## return retVal
|
||||
|
Loading…
Reference in New Issue
Block a user
Not sure about the copyright. Technically this is no longer property of bf, so if you want, you can put in your name (or Web3D Consortium as you're a member there) and current year