Skip to content

Commit dd0f5b6

Browse files
committed
Default open file path set to auto textures path
Relative Paths Added to Options Screenshots updated.
1 parent bdf1734 commit dd0f5b6

5 files changed

Lines changed: 232 additions & 28 deletions

File tree

__init__.py

Lines changed: 232 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"name": "PBR",
2121
"description": "PBR Workflow Tools",
2222
"author": "Digiography.Studio",
23-
"version": (1, 2, 0),
23+
"version": (1, 5, 0),
2424
"blender": (2, 79, 0),
2525
"location": "Properties > Material > PBR Material",
2626
"wiki_url": "https://github.com/Digiography/blender_addon_pbr/wiki",
@@ -192,7 +192,7 @@ def execute(self, context):
192192
node.color_space = 'NONE'
193193
node.name='ds_pbr_texture_normal'
194194
_material_links.new(node.outputs['Color'], node_map.inputs['Color'])
195-
195+
196196
ds_pbr_auto_textures.execute(self,context)
197197

198198
return {'FINISHED'}
@@ -297,6 +297,11 @@ class ds_pbr_addon_prefs(AddonPreferences):
297297
description="Add Metaliic Map Node",
298298
default = False
299299
)
300+
option_relative = BoolProperty(
301+
name="Relative Paths",
302+
description="Use Relative Paths for images.",
303+
default = True
304+
)
300305
option_metallic = FloatProperty(
301306
name = "Metaliic",
302307
description = "A float property",
@@ -311,13 +316,14 @@ class ds_pbr_addon_prefs(AddonPreferences):
311316
min = 0.000,
312317
max = 1.000
313318
)
314-
319+
315320
def draw(self, context):
316321

317322
layout = self.layout
318323

319324
layout.label('Defaults',icon='PREFERENCES')
320325

326+
layout.prop(self, 'option_relative')
321327
layout.prop(self, 'option_ao_map')
322328
layout.prop(self, 'option_metallic_map')
323329
layout.prop(self, 'option_metallic')
@@ -339,6 +345,13 @@ def get_option_metallic_map(self):
339345
def set_option_metallic_map(self, value):
340346
self["_option_metallic_map"] = value
341347

348+
def get_option_relative(self):
349+
if "_option_relative" not in self:
350+
self["_option_relative"]=bpy.context.user_preferences.addons[__name__].preferences.option_relative
351+
return self["_option_relative"]
352+
def set_option_relative(self, value):
353+
self["_option_relative"] = value
354+
342355
option_ao_map = BoolProperty(
343356
name="Ambient Occlusion",
344357
description="Add Ambient Occlusion Map via RGB Mix Node",
@@ -351,15 +364,156 @@ def set_option_metallic_map(self, value):
351364
get = get_option_metallic_map,
352365
set = set_option_metallic_map
353366
)
367+
option_relative = BoolProperty(
368+
name="Relative Paths",
369+
description="Use Relative Paths for images.",
370+
get = get_option_relative,
371+
set = set_option_relative
372+
)
354373
textures_path = StringProperty(
355-
name="Textures Path",
374+
name="Auto Textures Path",
356375
subtype='DIR_PATH',
357376
)
358377
option_nodes_type = StringProperty(
359378
name="Nodes Type",
360379
description="Nodes Type",
361380
default = ''
362381
)
382+
383+
class ds_pbr_texture_base_color(bpy.types.Operator):
384+
bl_idname = "ds_pbr.base_color"
385+
bl_label = "Base Color"
386+
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
387+
bl_context = "material"
388+
389+
option_relative = bpy.props.BoolProperty(name="Relative")
390+
391+
def execute(self, context):
392+
_nodes = context.material.node_tree.nodes
393+
if self.option_relative==True:
394+
_filepath=bpy.path.relpath(self.filepath)
395+
else:
396+
_filepath=bpy.path.abspath(self.filepath)
397+
_nodes['ds_pbr_texture_base_color'].image=bpy.data.images.load(_filepath)
398+
return {'FINISHED'}
399+
400+
def invoke(self, context, event):
401+
if not self.filepath and context.material.ds_pbr_material_options.textures_path:
402+
self.filepath = context.material.ds_pbr_material_options.textures_path
403+
self.option_relative=context.material.ds_pbr_material_options.option_relative
404+
context.window_manager.fileselect_add(self)
405+
return {'RUNNING_MODAL'}
406+
407+
class ds_pbr_texture_normal(bpy.types.Operator):
408+
bl_idname = "ds_pbr.texture_normal"
409+
bl_label = "Normal"
410+
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
411+
bl_context = "material"
412+
413+
option_relative = bpy.props.BoolProperty(name="Relative")
414+
415+
def execute(self, context):
416+
_nodes = context.material.node_tree.nodes
417+
if self.option_relative==True:
418+
_filepath=bpy.path.relpath(self.filepath)
419+
else:
420+
_filepath=bpy.path.abspath(self.filepath)
421+
_nodes['ds_pbr_texture_normal'].image=bpy.data.images.load(_filepath)
422+
return {'FINISHED'}
423+
424+
def invoke(self, context, event):
425+
if not self.filepath and context.material.ds_pbr_material_options.textures_path:
426+
self.filepath = context.material.ds_pbr_material_options.textures_path
427+
self.option_relative=context.material.ds_pbr_material_options.option_relative
428+
context.window_manager.fileselect_add(self)
429+
return {'RUNNING_MODAL'}
430+
431+
class ds_pbr_texture_ao(bpy.types.Operator):
432+
bl_idname = "ds_pbr.texture_ao"
433+
bl_label = "Ambient Occlusion"
434+
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
435+
bl_context = "material"
436+
437+
option_relative = bpy.props.BoolProperty(name="Relative")
438+
439+
def execute(self, context):
440+
_nodes = context.material.node_tree.nodes
441+
if self.option_relative==True:
442+
_filepath=bpy.path.relpath(self.filepath)
443+
else:
444+
_filepath=bpy.path.abspath(self.filepath)
445+
_nodes['ds_pbr_texture_ao'].image=bpy.data.images.load(_filepath)
446+
return {'FINISHED'}
447+
448+
def invoke(self, context, event):
449+
if not self.filepath and context.material.ds_pbr_material_options.textures_path:
450+
self.filepath = context.material.ds_pbr_material_options.textures_path
451+
self.option_relative=context.material.ds_pbr_material_options.option_relative
452+
context.window_manager.fileselect_add(self)
453+
return {'RUNNING_MODAL'}
454+
455+
class ds_pbr_texture_metallic(bpy.types.Operator):
456+
bl_idname = "ds_pbr.texture_metallic"
457+
bl_label = "Metallic"
458+
bl_context = "material"
459+
460+
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
461+
option_relative = bpy.props.BoolProperty(name="Relative")
462+
463+
def execute(self, context):
464+
_nodes = context.material.node_tree.nodes
465+
if self.option_relative==True:
466+
_filepath=bpy.path.relpath(self.filepath)
467+
else:
468+
_filepath=bpy.path.abspath(self.filepath)
469+
_nodes['ds_pbr_texture_metallic'].image=bpy.data.images.load(_filepath)
470+
return {'FINISHED'}
471+
472+
def invoke(self, context, event):
473+
if not self.filepath and context.material.ds_pbr_material_options.textures_path:
474+
self.filepath = context.material.ds_pbr_material_options.textures_path
475+
self.option_relative=context.material.ds_pbr_material_options.option_relative
476+
context.window_manager.fileselect_add(self)
477+
return {'RUNNING_MODAL'}
478+
479+
class ds_pbr_texture_roughness(bpy.types.Operator):
480+
bl_idname = "ds_pbr.texture_roughness"
481+
bl_label = "Roughness"
482+
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
483+
bl_context = "material"
484+
option_relative = bpy.props.BoolProperty(name="Relative")
485+
486+
def execute(self, context):
487+
_nodes = context.material.node_tree.nodes
488+
if self.option_relative==True:
489+
_filepath=bpy.path.relpath(self.filepath)
490+
else:
491+
_filepath=bpy.path.abspath(self.filepath)
492+
_nodes['ds_pbr_texture_roughness'].image=bpy.data.images.load(_filepath)
493+
return {'FINISHED'}
494+
495+
def invoke(self, context, event):
496+
if not self.filepath and context.material.ds_pbr_material_options.textures_path:
497+
self.filepath = context.material.ds_pbr_material_options.textures_path
498+
self.option_relative=context.material.ds_pbr_material_options.option_relative
499+
context.window_manager.fileselect_add(self,)
500+
return {'RUNNING_MODAL'}
501+
502+
class ds_pbr_render_cycles(bpy.types.Operator):
503+
bl_idname = "ds_pbr.render_cycles"
504+
bl_label = "CYCLES"
505+
bl_context = "scene"
506+
def execute(self, context):
507+
bpy.context.scene.render.engine='CYCLES'
508+
return {'FINISHED'}
509+
510+
class ds_pbr_render_game(bpy.types.Operator):
511+
bl_idname = "ds_pbr.render_game"
512+
bl_label = "BLENDER_GAME"
513+
bl_context = "scene"
514+
def execute(self, context):
515+
bpy.context.scene.render.engine='BLENDER_GAME'
516+
return {'FINISHED'}
363517

364518
class ds_pbr_material(Panel):
365519

@@ -385,51 +539,93 @@ def draw(self, context):
385539

386540
layout.label('Textures',icon='IMASEL')
387541

388-
split = layout.split(0.30)
389-
split.label('Base Color')
390-
split.template_ID(_nodes['ds_pbr_texture_base_color'], 'image', open='image.open')
391-
392-
if (_ds_pbr_material_options.option_metallic_map == True):
542+
row = layout.row(align=True)
543+
col = row.split(percentage=0.3)
544+
col.label(ds_pbr_texture_base_color.bl_label)
545+
if _nodes['ds_pbr_texture_base_color'].image:
546+
col.template_ID(_nodes['ds_pbr_texture_base_color'], "image", "image.open")
547+
else:
548+
col.operator(ds_pbr_texture_base_color.bl_idname, icon="FILE_FOLDER",text="Select Image")
393549

394-
if ('ds_pbr_texture_metallic' in _nodes):
550+
if (_ds_pbr_material_options.option_metallic_map == True and 'ds_pbr_texture_metallic' in _nodes):
395551

396-
split = layout.split(0.30)
397-
split.label('Metallic')
398-
split.template_ID(_nodes['ds_pbr_texture_metallic'], 'image', open='image.open')
552+
row = layout.row(align=True)
553+
col = row.split(percentage=0.3)
554+
col.label(ds_pbr_texture_metallic.bl_label)
555+
556+
if _nodes['ds_pbr_texture_metallic'].image:
557+
col.template_ID(_nodes['ds_pbr_texture_metallic'], "image", "image.open")
558+
else:
559+
col.operator(ds_pbr_texture_metallic.bl_idname, icon="FILE_FOLDER",text="Select Image")
399560

400561
if (_ds_pbr_material_options.option_ao_map == True):
401562

563+
row = layout.row(align=True)
564+
col = row.split(percentage=0.3)
565+
col.label(ds_pbr_texture_ao.bl_label)
402566
if ('ds_pbr_texture_ao' in _nodes):
567+
if _nodes['ds_pbr_texture_ao'].image:
568+
col.template_ID(_nodes['ds_pbr_texture_ao'], "image", "image.open")
569+
else:
570+
col.operator(ds_pbr_texture_ao.bl_idname, icon="FILE_FOLDER",text="Select Image")
571+
572+
row = layout.row(align=True)
573+
col = row.split(percentage=0.3)
574+
col.label(ds_pbr_texture_normal.bl_label)
575+
if _nodes['ds_pbr_texture_normal'].image:
576+
col.template_ID(_nodes['ds_pbr_texture_normal'], "image", "image.open")
577+
else:
578+
col.operator(ds_pbr_texture_normal.bl_idname, icon="FILE_FOLDER",text="Select Image")
579+
580+
row = layout.row(align=True)
581+
col = row.split(percentage=0.3)
582+
col.label(ds_pbr_texture_roughness.bl_label)
583+
if _nodes['ds_pbr_texture_roughness'].image:
584+
col.template_ID(_nodes['ds_pbr_texture_roughness'], "image", "image.open")
585+
else:
586+
col.operator(ds_pbr_texture_roughness.bl_idname, icon="FILE_FOLDER",text="Select Image")
587+
588+
layout.label('Options',icon='NODETREE')
403589

404-
split = layout.split(0.30)
405-
split.label('Ambient Occulussion')
406-
split.template_ID(_nodes['ds_pbr_texture_ao'], 'image', open='image.open')
407-
408-
split = layout.split(0.30)
409-
split.label('Normal')
410-
split.template_ID(_nodes['ds_pbr_texture_normal'], 'image', open='image.open')
411-
412-
split = layout.split(0.30)
413-
split.label('Roughness')
414-
split.template_ID(_nodes['ds_pbr_texture_roughness'], 'image', open='image.open')
415-
416-
layout.label('Auto Textures',icon='IMASEL')
417590
layout.prop(_ds_pbr_material_options, "textures_path")
591+
layout.prop(_ds_pbr_material_options, "option_relative")
592+
593+
if not bpy.data.filepath and _ds_pbr_material_options.option_relative == True:
594+
layout.label('Blender file not saved. Required for relative paths.',icon='INFO')
418595

419596
layout.label('Optional Nodes',icon='NODETREE')
420597

421598
layout.prop(_ds_pbr_material_options, "option_ao_map")
422599
layout.prop(_ds_pbr_material_options, "option_metallic_map")
600+
601+
602+
if (bpy.context.scene.render.engine != 'CYCLES' and bpy.context.scene.render.engine != 'BLENDER_GAME'):
603+
604+
layout.label('Cycles or Blender Game Render Engine required for PBR','INFO')
605+
row = layout.row(align=True)
606+
col = row.split(percentage=0.5)
607+
col.operator('ds_pbr.render_cycles')
608+
col.operator('ds_pbr.render_game')
423609

424-
layout.operator("ds_pbr.nodes_metallic_roughness")
425-
layout.operator("ds_pbr.nodes_specular_gloss")
610+
row = layout.row(align=True)
611+
col = row.split(percentage=0.5)
612+
col.operator("ds_pbr.nodes_metallic_roughness")
613+
col.operator("ds_pbr.nodes_specular_gloss")
426614

427615
layout.separator()
428616

429617
def register():
430618

431619
from bpy.utils import register_class
432620

621+
register_class(ds_pbr_render_cycles)
622+
register_class(ds_pbr_render_game)
623+
register_class(ds_pbr_texture_base_color)
624+
register_class(ds_pbr_texture_normal)
625+
register_class(ds_pbr_texture_ao)
626+
register_class(ds_pbr_texture_metallic)
627+
register_class(ds_pbr_texture_roughness)
628+
433629
register_class(ds_pbr_addon_prefs)
434630
register_class(ds_pbr_material_options)
435631
register_class(ds_pbr_nodes_remove)
@@ -444,6 +640,14 @@ def unregister():
444640

445641
from bpy.utils import unregister_class
446642

643+
unregister_class(ds_pbr_render_cycles)
644+
unregister_class(ds_pbr_render_game)
645+
unregister_class(ds_pbr_texture_base_color)
646+
unregister_class(ds_pbr_texture_normal)
647+
unregister_class(ds_pbr_texture_ao)
648+
unregister_class(ds_pbr_texture_metallic)
649+
unregister_class(ds_pbr_texture_roughness)
650+
447651
unregister_class(ds_pbr_addon_prefs)
448652
unregister_class(ds_pbr_material_options)
449653
unregister_class(ds_pbr_nodes_remove)
1.9 KB
Loading

screenshots/material_panel_m_r.png

16.3 KB
Loading

screenshots/pbr_fullscreen.png

1.07 MB
Loading

screenshots/pbr_prefs.png

-298 Bytes
Loading

0 commit comments

Comments
 (0)