2
$\begingroup$

I'm creating an image file importer based off the operator_file_import template. I want to set script so that it recognizes image files, because right now it's only recognizing text. How do I go about defining a list of extensions that show up in the file browser when I launch the script? Right now, based on the starting template, the only thing I can import is a .txt file.

Here is the code - The generic comments are still there and anything that I changed is indicated by a comment/CHANGED tag.

import bpy
from bpy.types import Operator
import collections
import os
from bpy.props import (
        StringProperty,
        BoolProperty,
        EnumProperty,
        IntProperty,
        FloatProperty,
        CollectionProperty,
        )
from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator


#CHANGED read definition to class name
def read_pbr_textures(context, filepath, use_some_setting):   
    print("running read_pbr_textures..")
    f = open(filepath, 'r', encoding='utf-8')
    data = f.read()
    f.close()

    # would normally load the data here
    print(data)

    return {'FINISHED'}


#CHANGED class name
class ImportPbrTextures(Operator, ImportHelper):   
    """This appears in the tooltip of the operator and in the generated docs"""
    bl_idname = "import_test.pbr_textures"  # important since its how bpy.ops.import_test.some_data is constructed
    bl_label = "Import PBR Textures"

#CHANGED filename_ext to png
    # ImportHelper mixin class uses this
    filename_ext = "*.png"

    filter_glob = StringProperty(
            default="*.png",
            options={'HIDDEN'},
            maxlen=255,  # Max internal buffer length, longer would be clamped.
            )

    # List of operator properties, the attributes will be assigned
    # to the class instance from the operator settings before calling.
    use_setting = BoolProperty(
            name="Example Boolean",
            description="Example Tooltip",
            default=True,
            )

    type = EnumProperty(
            name="Example Enum",
            description="Choose between two items",
            items=(('OPT_A', "First Option", "Description one"),
                   ('OPT_B', "Second Option", "Description two")),
            default='OPT_A',
            )

    def execute(self, context):
        return read_some_data(context, self.filepath, self.use_setting)


# Only needed if you want to add into a dynamic menu
def menu_func_import(self, context):
    self.layout.operator(ImportPbrTextures.bl_idname, text="Text Import Operator")

#CHANGED class registration to ImportPbrTextures class
def register():
    bpy.utils.register_class(ImportPbrTextures)
    bpy.types.INFO_MT_file_import.append(menu_func_import)


def unregister():
    bpy.utils.unregister_class(ImportPbrTextures)
    bpy.types.INFO_MT_file_import.remove(menu_func_import)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.import_test.pbr_textures('INVOKE_DEFAULT')
$\endgroup$
  • $\begingroup$ This question isn't spesific to image importing, its just about extensions. $\endgroup$ – ideasman42 Jun 2 '16 at 8:14
  • $\begingroup$ The script doesn't run AttributeError: Calling operator "bpy.ops.import_test.some_data" error, could not be found $\endgroup$ – ideasman42 Jun 2 '16 at 8:18
  • $\begingroup$ The code works, ie only shows png files, however you are test calling import_test.some_data rather than import_test.pbr_textures ... perhaps the former still had ".txt" as a glob. $\endgroup$ – batFINGER Jun 2 '16 at 8:18
  • $\begingroup$ script now works and points to .png files. Problem was as batFINGER said, bpy.ops.import_test.some_data needed to be changed to import_test.pbr_textures $\endgroup$ – lvxejay Jun 2 '16 at 8:29
  • $\begingroup$ All this code does is point to the image files now. Upon trying to load and read the images, I am met with this error: line 64, in execute NameError: name 'read_some_data' is not defined How do I define the script to read these files? Or more specifically, how can I make this script load the image into a texture node? $\endgroup$ – lvxejay Jun 2 '16 at 9:02
2
$\begingroup$

In the operator's filter_glob property, (which you've already defined), you can define multiple extensions using the ; separator, eg:

filter_glob = StringProperty(
        default="*.png;*.jpg;*.jpeg;*.bmp;*.exr",
        options={'HIDDEN'},
        )

If you want to make a list of all extensions Blender supports you can use. bpy.path.extensions_image eg:

"*" + ";*".join(bpy.path.extensions_image)
$\endgroup$
  • $\begingroup$ works properly! File importer script now points to multiple extensions $\endgroup$ – lvxejay Jun 2 '16 at 9:05
  • $\begingroup$ @lvxejay bpy.path.extesions_image is a set of all image formats supported (by extension) $\endgroup$ – batFINGER Jun 2 '16 at 13:54
  • $\begingroup$ @ideasman42 Where are these operator's properties documented. I cannot to seem to find any description of them besides in Blender source. $\endgroup$ – Zingam May 2 '18 at 6:24
0
$\begingroup$

Here is an example from http://web.purplefrog.com/~thoth/blender/python-cookbook/image-to-material-node.html :

def image_for(fname):
    candidates = [ img for img in bpy.data.images if img.filepath == fname]
    if len(candidates)<1:
        return bpy.data.images.load(fname)
    else:
        return candidates[0]

def node_of_type(nodes, type):
    for node in nodes:
        if node.type == type:
            return node

def mission1(fname):

    mat = bpy.data.materials.get("material")
    if mat is None:
        mat = bpy.data.materials.new("material")

    mat.use_nodes = True
    nodes = mat.node_tree.nodes

    n1 = node_of_type(nodes, "TEX_IMAGE")
    if n1 is None:
        n1 = nodes.new("ShaderNodeTexImage")

    n1.location = (-200,0)
    n1.image = image_for(fname)

    bsdf = node_of_type(nodes, 'BSDF_DIFFUSE')

    mat.node_tree.links.new(bsdf.inputs[0], n1.outputs[0])

    coord = node_of_type(nodes, 'TEX_COORD')
    if coord is None:
        coord = nodes.new('ShaderNodeTexCoord')
    coord.location = (-400,0)

    mat.node_tree.links.new(n1.inputs['Vector'], coord.outputs['UV'])

    return mat

mat = mission1("/home/thoth/art/dancing-bear/bear384.png")
bpy.context.active_object.data.materials[0] = mat
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.