3
$\begingroup$

I now have the file browser, and I've found out how to load the texture into the node but not from the file browser. I have to type the file path in manually, and I had to put it in a different class that was activated with a bool... so, how can I activate the file browser instead?

enter image description here

code

import bpy
import os
from bpy.types import (Menu, PropertyGroup)
from bpy.props import (BoolProperty, FloatProperty, EnumProperty, StringProperty)
from bpy_extras.io_utils import ImportHelper

def update_texture(self, context):
    path = self.screen_texture.value
    img = bpy.data.images.load(filepath = path)

    nt = bpy.data.materials['Screen'].node_tree
    n = nt.nodes["screen_texture"].image = img

class IgnitProperties(bpy.types.PropertyGroup):

    screen_path = StringProperty(
       name="Browse Image:",
       description="Loads the texture for the screen",
       maxlen= 1024,
       subtype='FILE_PATH',
       update=update_texture
   )

class IdentifierFileSelector(bpy.types.Operator, ImportHelper):
    bl_label = "File Browser"
    bl_idname = "macbook_controller.identifier_file_selector"

    def execute(self, context):
        fdir = self.properties.filepath

        # Screen Texture


        return{'FINISHED'}

class IGLayoutDemoPanel(bpy.types.Panel):
    """Creates a Panel in the scene context of the properties editor"""
    bl_label = "MacBook Controller"
    bl_idname = "macbook_controller.macbook_controller"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        layout = self.layout

        scene = context.scene

        # Screen Texture
        layout.label(text = "Screen Texture:")
        layout.prop(scene.ignit_panel, "screen_path", text="")
$\endgroup$
  • $\begingroup$ related: blender.stackexchange.com/questions/14572/… $\endgroup$ – zeffii Dec 29 '15 at 7:53
  • $\begingroup$ Possible duplicate of How to create a Folder Dialog? $\endgroup$ – p2or Dec 29 '15 at 8:39
  • $\begingroup$ inside the execute function is where you could include the code that updates the node's .img , or you could call a function from there and pass it the filepath. $\endgroup$ – zeffii Dec 29 '15 at 8:47
  • 2
    $\begingroup$ it is kind of an awkward question. being able to ask and answer the question relies on understanding several concepts. Not a bad question, just tricky to form it as a question that will benefit more readers. $\endgroup$ – zeffii Dec 29 '15 at 9:14
  • 1
    $\begingroup$ @MatthewInglis In addition to zeffii's comment: Please consider that this site is not a personal support forum, it's is run by people who like to use blender and volunteer their time to help others. Try to abstract/recap/compress your questions as best you can instead of pasting your whole code in here and ask for a solution. This will help you to find the issue on your own and also will help future visitors. Also avoid asking multiple questions at once. 'How to create a folder dialog, import an image and using this for my material?' is simply too broad and may get down voted. Hope this helps. $\endgroup$ – p2or Dec 29 '15 at 10:24
3
$\begingroup$

Use the ImportHelper - a class that wraps the FileBrowser.

import os
from bpy_extras.io_utils import ImportHelper

class IdentifierFileSelector(bpy.types.Operator, ImportHelper):
    bl_idname = "something.identifier_file_selector"
    bl_label = "some folder"

    def execute(self, context):
        fdir = self.properties.filepath

        # do something with fdir here  (fullpath)

        return{'FINISHED'}

bl_idname

  • Should be lowercase.
  • For your own sanity it's useful to make it consistent with the class name. If the class name is XxxxxxYyyyZzzzzz then a predictable bl_idname would be "xxxxx_yyyyy_zzzz"
  • The prefix (i called it "something" in the code above) is a way for you to create a namespace for your own operators. Each operator is found in bpy.ops.* therefor your operator would be found at bpy.ops.something.identifier_file_selector

In this scenario, the StringProperty isn't something you want to be typing into ever. The update function is a little overkill then. See that property as visual reference to show you which file you picked.

class IgnitProperties(bpy.types.PropertyGroup):
    screen_path = StringProperty(description="Contains path to a texture")


class IdentifierFileSelector(bpy.types.Operator, ImportHelper):
    bl_label = "File Browser"
    bl_idname = "macbook_controller.identifier_file_selector"

    def execute(self, context):
        # Screen Texture
        img = bpy.data.images.load(filepath=self.properties.filepath)

        # update the node
        nt = bpy.data.materials['Screen'].node_tree
        n = nt.nodes["screen_texture"].image = img

        # also update this StringProperty so it reflects what you picked 
        context.scene.ignit_panel.screen_path = self.properties.filepath
        return{'FINISHED'}

your draw

scn = bpy.context.scene
row = layout.row()
row.prop(scn.ignit_panel, "screen_path")  # <-- just for display purposes
row.operator("macbook_controller.identifier_file_selector", text="", icon='FILE')
$\endgroup$
  • $\begingroup$ Do I need to have the bl_ things, I have them in another class, do they have to be in both? $\endgroup$ – mr-matt Dec 29 '15 at 8:28
  • $\begingroup$ Gee, you're the best! I'm not sure if this would mean much to you but when I finish this model I'm email it to you for free, just as a token of my appreciation! (seeing as though like half the code here is based off your code!) $\endgroup$ – mr-matt Dec 29 '15 at 9:17
  • $\begingroup$ We're all building on the shoulders of giants. What Blender bpy lacks in documentation is made up for by its sheer amount of free open source add-on examples. (except you might have to wade through a tonne of code to find the nuggets of interest) $\endgroup$ – zeffii Dec 31 '15 at 13:52

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.