My __init__.py
script creates a panel that lets a user select the figure (typically a humanoid figure imported from Poser) she wants to give shaders to, defines the figure type and then sets the path to the image files used in the shader script.
The bit that creates the panel:
class MatShaderPanel(bpy.types.Panel):
"""Create shaders for your Poser figure: Panel"""
bl_label = "Figure Files Util"
bl_idname = "MATERIALS_PT_shaders"
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
def draw(self, context):
# sets renderer to Cycles
if bpy.context.scene.render.engine == 'BLENDER_RENDER':
bpy.context.scene.render.engine = 'CYCLES'
layout = self.layout
obj = context.object
row1 = layout.row()
row1.label(text='Figure Name')
row2 = layout.row()
row2.label(text="Active object is: " + obj.name)
row3 = layout.row()
row3.prop(obj, "name")
row4 = layout.row()
row4.prop(context.scene, 'imag_path')
row5 = layout.row()
row5.operator("object.run_script", text='Apply Shaders')
row5.enabled = context.scene.show_row5
I believe that I register that 'imag_path' property seen in row4.prop(context.scene, 'imag_path') in:
def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.imag_path = bpy.props.StringProperty( \
name="Images Path",
default="",
description="Defines the path to your images",
subtype='DIR_PATH')
bpy.types.Scene.figur_obj = bpy.props.StringProperty( \
name="Figure Type",
default="",
description="Defines the base mesh name of your figure")
def unregister():
del bpy.types.Scene.imag_path
del bpy.types.Scene.figur_obj
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
However, the imag_path
property doesn't appear to be available to the rest of the script. I was thinking of making it a global variable by setting it right after the import statements, but am not quite clear on whether that's the right approach. For example, this (in a subsequent function):
def shadersSetup():
csvFile = imag_path + "/" + "image_List.csv"
...fails, as imag_path
isn't available to shaderSetup()
.
Think I need to read up on property scope vs variable scope and how all that relates to modules. This doesn't discuss it any.
Update
Not the full answer yet, so I can't call this solved, but I did incorporate both batFINGER's and TLousky's suggestions. Unfortunately, I am still getting an error based on what gets written to imag_path in that DIR_PATH
property(?) which allows the user to go out and find the folder containing the images. I mean the last part of the resultant path looks exactly right, but the first bit seems not quite right, somehow: here is the error:
Traceback (most recent call last): File "/home/robyn/.config/blender/2.76/scripts/addons/make_Shaders/__init__.py", line 102, in execute shadersSetup() File "/home/robyn/.config/blender/2.76/scripts/addons/make_Shaders/__init__.py", line 124, in shadersSetup iList = readImgList(csvFile) File "/home/robyn/.config/blender/2.76/scripts/addons/make_Shaders/__init__.py", line 113, in readImgList with open(fname, 'r') as csvfile: FileNotFoundError: [Errno 2] No such file or directory: '//../../AllTextures/AllSkin/PS_Syri/image_list.csv'
The part of the path displayed is correct, exactly. But the script seems to expect a fully-qualified path. And I tried: csvFile = os.path.join(os.path.abspath(scn.imag_path), "image_list.csv")
. Still gave me a truncated path.
I do want to say I thoroughly appreciate your help.
2nd Update
Since the problem with the path still exists, I've been running a series of test on this path issue, double-checking that the path and the file do indeed exist. I did change the csv_Path property to take the file name now:
bpy.types.Scene.csv_path = bpy.props.StringProperty(name="CSV Path",
default="*.csv",
maxlen=1024,
description="CSV location",
subtype='FILE_PATH')
Mind you, I thought by doing a default="*.csv", it would only display that csv file in the folder, but it displays all files.
Here is the path testing code:
scn = bpy.context.scene
csvFile = os.path.abspath(scn.csv_path)
csvPath = csvFile[:-14]
fullyQP = os.path.join(os.getcwd(), csvFile)
print("scn.csv_path: " + scn.csv_path)
print("csvFile: " + csvFile)
print("csvPath: " + csvPath)
print("Joined cwd and the CSV: " + fullyQP)
print(os.path.isdir(csvPath))
Here is the output to the print()s:
scn.csv_path: //../../AllTextures/AllSkin/PS_Syri/image_List.csv
csvFile: //AllTextures/AllSkin/PS_Syri/image_List.csv
csvPath: //AllTextures/AllSkin/PS_Syri/
Joined cwd and the CSV: //AllTextures/AllSkin/PS_Syri/image_List.csv
False
The last is most significant, as it is not seeing that relative path as a workable path. In my preferences, under File, I have Relative Paths ticked. I'm completely baffled as to how to proceed.
ETA: I guess if I can't get this working, I might need to have the users put those csv files (and image files) where Blender and the script can easily find them. Thing is: what I was hoping was that they could use existing folders somewhere in their /runtime/textures/character directories instead of having to make a copy to their Blender projects folders.
os.path.join(scene.imag_path, "image_list.csv")
is good practice. $\endgroup$