Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'render_povray/ui.py')
-rw-r--r--render_povray/ui.py749
1 files changed, 596 insertions, 153 deletions
diff --git a/render_povray/ui.py b/render_povray/ui.py
index e15a9374..6bdadccf 100644
--- a/render_povray/ui.py
+++ b/render_povray/ui.py
@@ -22,11 +22,15 @@
import bpy
import sys # really import here and in render.py?
import os # really import here and in render.py?
+import addon_utils
+from time import sleep
from os.path import isfile
+from bpy.app.handlers import persistent
from bl_operators.presets import AddPresetBase
from bpy.utils import register_class, unregister_class
from bpy.types import (
Operator,
+ Menu,
UIList,
Panel,
Brush,
@@ -43,17 +47,29 @@ from bl_ui import properties_output
for member in dir(properties_output):
subclass = getattr(properties_output, member)
try:
- subclass.COMPAT_ENGINES.add('POVRAY')
+ subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
except:
pass
del properties_output
+from bl_ui import properties_freestyle
+for member in dir(properties_freestyle):
+ subclass = getattr(properties_freestyle, member)
+ try:
+ if not (subclass.bl_space_type == 'PROPERTIES'
+ and subclass.bl_context == "render"):
+ subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
+ #subclass.bl_parent_id = "RENDER_PT_POV_filter"
+ except:
+ pass
+del properties_freestyle
+
from bl_ui import properties_view_layer
for member in dir(properties_view_layer):
subclass = getattr(properties_view_layer, member)
try:
- subclass.COMPAT_ENGINES.add('POVRAY')
+ subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
except:
pass
del properties_view_layer
@@ -242,19 +258,136 @@ for member in dir(
pass
del properties_particle
-# Example of wrapping every class 'as is'
-from bl_ui import properties_output
-for member in dir(properties_output):
- subclass = getattr(properties_output, member)
- try:
- subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
- except:
- pass
-del properties_output
+############# POV-Centric WORSPACE #############
+@persistent
+def povCentricWorkspace(dummy):
+ """Set up a POV centric Workspace if addon was activated and saved as default renderer
+
+ This would bring a ’_RestrictData’ error because UI needs to be fully loaded before
+ workspace changes so registering this function in bpy.app.handlers is needed.
+ By default handlers are freed when loading new files, but here we want the handler
+ to stay running across multiple files as part of this add-on. That is why the the
+ bpy.app.handlers.persistent decorator is used (@persistent) above.
+ """
+
+ wsp = bpy.data.workspaces.get('Scripting')
+ context = bpy.context
+ if wsp is not None and context.scene.render.engine == 'POVRAY_RENDER':
+ new_wsp = bpy.ops.workspace.duplicate({'workspace': wsp})
+ bpy.data.workspaces['Scripting.001'].name='POV'
+ # Already done it would seem, but explicitly make this workspaces the active one
+ context.window.workspace = bpy.data.workspaces['POV']
+ pov_screen = bpy.data.workspaces['POV'].screens[0]
+ pov_workspace = pov_screen.areas
+
+
+ override = bpy.context.copy()
+
+ for area in pov_workspace:
+ if area.type == 'VIEW_3D':
+ for region in [r for r in area.regions if r.type == 'WINDOW']:
+ for space in area.spaces:
+ if space.type == 'VIEW_3D':
+ #override['screen'] = pov_screen
+ override['area'] = area
+ override['region']= region
+ #bpy.data.workspaces['POV'].screens[0].areas[6].spaces[0].width = 333 # Read only, how do we set ?
+ #This has a glitch:
+ #bpy.ops.screen.area_move(override, x=(area.x + area.width), y=(area.y + 5), delta=100)
+ #bpy.ops.screen.area_move(override, x=(area.x + 5), y=area.y, delta=-100)
+
+ bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'TEXT_EDITOR')
+ space.show_region_ui = True
+ #bpy.ops.screen.region_scale(override)
+ #bpy.ops.screen.region_scale()
+ break
+
+ elif area.type == 'CONSOLE':
+ for region in [r for r in area.regions if r.type == 'WINDOW']:
+ for space in area.spaces:
+ if space.type == 'CONSOLE':
+ #override['screen'] = pov_screen
+ override['area'] = area
+ override['region']= region
+ bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'INFO')
+
+ break
+ elif area.type == 'INFO':
+ for region in [r for r in area.regions if r.type == 'WINDOW']:
+ for space in area.spaces:
+ if space.type == 'INFO':
+ #override['screen'] = pov_screen
+ override['area'] = area
+ override['region']= region
+ bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'CONSOLE')
+
+ break
+
+ elif area.type == 'TEXT_EDITOR':
+ for region in [r for r in area.regions if r.type == 'WINDOW']:
+ for space in area.spaces:
+ if space.type == 'TEXT_EDITOR':
+ #override['screen'] = pov_screen
+ override['area'] = area
+ override['region']= region
+ #bpy.ops.screen.space_type_set_or_cycle(space_type='VIEW_3D')
+ #space.type = 'VIEW_3D'
+ bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'VIEW_3D')
+
+ #bpy.ops.screen.area_join(override, cursor=(area.x, area.y + area.height))
+
+ break
+
+
+ if area.type == 'VIEW_3D':
+ for region in [r for r in area.regions if r.type == 'WINDOW']:
+ for space in area.spaces:
+ if space.type == 'VIEW_3D':
+ #override['screen'] = pov_screen
+ override['area'] = area
+ override['region']= region
+ bpy.ops.screen.region_quadview(override)
+ space.region_3d.view_perspective = 'CAMERA'
+ #bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'TEXT_EDITOR')
+ #bpy.ops.screen.region_quadview(override)
+
+
+
+
-class WORLD_MT_POV_presets(bpy.types.Menu):
+ bpy.data.workspaces.update()
+ # Already outliners but invert both types
+ pov_workspace[1].spaces[0].display_mode = 'LIBRARIES'
+ pov_workspace[3].spaces[0].display_mode = 'VIEW_LAYER'
+
+ '''
+ for window in bpy.context.window_manager.windows:
+ for area in [a for a in window.screen.areas if a.type == 'VIEW_3D']:
+ for region in [r for r in area.regions if r.type == 'WINDOW']:
+ context_override = {
+ 'window': window,
+ 'screen': window.screen,
+ 'area': area,
+ 'region': region,
+ 'space_data': area.spaces.active,
+ 'scene': bpy.context.scene
+ }
+ bpy.ops.view3d.camera_to_view(context_override)
+ '''
+
+
+ else:
+ print("default 'Scripting' workspace needed for POV centric Workspace")
+
+
+
+
+
+
+
+class WORLD_MT_POV_presets(Menu):
bl_label = "World Presets"
preset_subdir = "pov/world"
preset_operator = "script.execute_preset"
@@ -262,7 +395,7 @@ class WORLD_MT_POV_presets(bpy.types.Menu):
class WORLD_OT_POV_add_preset(AddPresetBase, Operator):
- '''Add a World Preset'''
+ """Add a World Preset"""
bl_idname = "object.world_preset_add"
bl_label = "Add World Preset"
@@ -324,6 +457,15 @@ def check_add_mesh_extra_objects():
return True
return False
+def check_render_freestyle_svg():
+ """Test if Freestyle SVG Exporter addon is activated
+
+ This addon is currently used to generate the SVG lines file
+ when Freestyle is enabled alongside POV
+ """
+ if "render_freestyle_svg" in bpy.context.preferences.addons.keys():
+ return True
+ return False
def locate_docpath():
"""POV can be installed with some include files.
@@ -373,31 +515,29 @@ def pov_context_tex_datablock(context):
"""Texture context type recreated as deprecated in blender 2.8"""
idblock = context.brush
- if idblock and bpy.context.scene.texture_context == 'OTHER':
+ if idblock and context.scene.texture_context == 'OTHER':
return idblock
# idblock = bpy.context.active_object.active_material
- idblock = bpy.context.scene.view_layers[
- "View Layer"
- ].objects.active.active_material
- if idblock:
+ idblock = context.view_layer.objects.active.active_material
+ if idblock and context.scene.texture_context == 'MATERIAL':
return idblock
- idblock = context.world
- if idblock:
+ idblock = context.scene.world
+ if idblock and context.scene.texture_context == 'WORLD':
return idblock
idblock = context.light
- if idblock:
+ if idblock and context.scene.texture_context == 'LIGHT':
return idblock
- if context.particle_system:
+ if context.particle_system and context.scene.texture_context == 'PARTICLES':
idblock = context.particle_system.settings
return idblock
idblock = context.line_style
- if idblock:
+ if idblock and context.scene.texture_context == 'LINESTYLE':
return idblock
@@ -688,7 +828,7 @@ class LIGHT_PT_POV_light(PovLampButtonsPanel, Panel):
draw = properties_data_light.DATA_PT_light.draw
-class LIGHT_MT_POV_presets(bpy.types.Menu):
+class LIGHT_MT_POV_presets(Menu):
"""Use this class to define preset menu for pov lights."""
bl_label = "Lamp Presets"
@@ -1114,9 +1254,8 @@ class WORLD_PT_POV_mist(WorldButtonsPanel, Panel):
class RENDER_PT_POV_export_settings(RenderButtonsPanel, Panel):
"""Use this class to define pov ini settingss buttons."""
-
- bl_label = "Start Options"
bl_options = {'DEFAULT_CLOSED'}
+ bl_label = "Auto Start"
COMPAT_ENGINES = {'POVRAY_RENDER'}
def draw_header(self, context):
@@ -1131,6 +1270,7 @@ class RENDER_PT_POV_export_settings(RenderButtonsPanel, Panel):
)
def draw(self, context):
+
layout = self.layout
scene = context.scene
@@ -1143,25 +1283,25 @@ class RENDER_PT_POV_export_settings(RenderButtonsPanel, Panel):
col.prop(scene.pov, "command_line_switches", text="")
split = layout.split()
- layout.active = not scene.pov.tempfiles_enable
- # if not scene.pov.tempfiles_enable:
- split.prop(scene.pov, "deletefiles_enable", text="Delete files")
- split.prop(scene.pov, "pov_editor", text="POV Editor")
+ #layout.active = not scene.pov.tempfiles_enable
+ if not scene.pov.tempfiles_enable:
+ split.prop(scene.pov, "deletefiles_enable", text="Delete files")
+ split.prop(scene.pov, "pov_editor", text="POV Editor")
- col = layout.column()
- col.prop(scene.pov, "scene_name", text="Name")
- col.prop(scene.pov, "scene_path", text="Path to files")
- # col.prop(scene.pov, "scene_path", text="Path to POV-file")
- # col.prop(scene.pov, "renderimage_path", text="Path to image")
+ col = layout.column()
+ col.prop(scene.pov, "scene_name", text="Name")
+ col.prop(scene.pov, "scene_path", text="Path to files")
+ # col.prop(scene.pov, "scene_path", text="Path to POV-file")
+ # col.prop(scene.pov, "renderimage_path", text="Path to image")
- split = layout.split()
- split.prop(scene.pov, "indentation_character", text="Indent")
- if scene.pov.indentation_character == 'SPACE':
- split.prop(scene.pov, "indentation_spaces", text="Spaces")
+ split = layout.split()
+ split.prop(scene.pov, "indentation_character", text="Indent")
+ if scene.pov.indentation_character == 'SPACE':
+ split.prop(scene.pov, "indentation_spaces", text="Spaces")
- row = layout.row()
- row.prop(scene.pov, "comments_enable", text="Comments")
- row.prop(scene.pov, "list_lf_enable", text="Line breaks in lists")
+ row = layout.row()
+ row.prop(scene.pov, "comments_enable", text="Comments")
+ row.prop(scene.pov, "list_lf_enable", text="Line breaks in lists")
class RENDER_PT_POV_render_settings(RenderButtonsPanel, Panel):
@@ -1414,7 +1554,7 @@ class RENDER_PT_POV_radiosity(RenderButtonsPanel, Panel):
col.prop(scene.pov, "radio_subsurface")
-class POV_RADIOSITY_MT_presets(bpy.types.Menu):
+class POV_RADIOSITY_MT_presets(Menu):
"""Use this class to define pov radiosity presets menu."""
bl_label = "Radiosity Presets"
@@ -1562,7 +1702,7 @@ class MODIFIERS_PT_POV_modifiers(ModifierButtonsPanel, Panel):
col.prop(ob.pov, "inside_vector")
-class MATERIAL_MT_POV_sss_presets(bpy.types.Menu):
+class MATERIAL_MT_POV_sss_presets(Menu):
"""Use this class to define pov sss preset menu."""
bl_label = "SSS Presets"
@@ -1872,7 +2012,7 @@ class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel):
sub = col.column()
sub.active = raym.gloss_factor < 1.0
sub.prop(raym, "gloss_threshold", text="Threshold")
- sub.prop(raym, "gloss_samples", text="Samples")
+ sub.prop(raym, "gloss_samples", text="Noise")
sub.prop(raym, "gloss_anisotropic", text="Anisotropic")
@@ -2178,7 +2318,7 @@ class MATERIAL_PT_POV_replacement_text(MaterialButtonsPanel, Panel):
col.prop(mat.pov, "replacement_text", text="")
-class TEXTURE_MT_POV_specials(bpy.types.Menu):
+class TEXTURE_MT_POV_specials(Menu):
"""Use this class to define pov texture slot operations buttons."""
bl_label = "Texture Specials"
@@ -2191,14 +2331,20 @@ class TEXTURE_MT_POV_specials(bpy.types.Menu):
layout.operator("texture.slot_paste", icon='PASTEDOWN')
-class TEXTURE_UL_POV_texture_slots(bpy.types.UIList):
- """Use this class to show pov texture slots list.""" # used?
-
- COMPAT_ENGINES = {'POVRAY_RENDER'}
+class WORLD_TEXTURE_SLOTS_UL_POV_layerlist(UIList):
+ """Use this class to show pov texture slots list.""" # XXX Not used yet
+ index: bpy.props.IntProperty(name='index')
def draw_item(
self, context, layout, data, item, icon, active_data, active_propname
):
+ world = context.scene.world # .pov
+ active_data = world.pov
+ # tex = context.texture #may be needed later?
+
+ # We could write some code to decide which icon to use here...
+ custom_icon = 'TEXTURE'
+
ob = data
slot = item
# ma = slot.name
@@ -2220,62 +2366,7 @@ class TEXTURE_UL_POV_texture_slots(bpy.types.UIList):
layout.label(text="", icon_value=icon)
-'''
-class MATERIAL_TEXTURE_SLOTS_UL_List(UIList):
- """Texture Slots UIList."""
-
-
- def draw_item(self, context, layout, material, item, icon, active_data,
- material_texture_list_index, index):
- material = context.material#.pov
- active_data = material
- #tex = context.texture #may be needed later?
-
-
- # We could write some code to decide which icon to use here...
- custom_icon = 'TEXTURE'
-
- # Make sure your code supports all 3 layout types
- if self.layout_type in {'DEFAULT', 'COMPACT'}:
- layout.label(item.name, icon = custom_icon)
-
- elif self.layout_type in {'GRID'}:
- layout.alignment = 'CENTER'
- layout.label("", icon = custom_icon)
-'''
-
-
-class WORLD_TEXTURE_SLOTS_UL_List(UIList):
- """Use this class to show pov texture slots list.""" # XXX Not used yet
-
- def draw_item(
- self,
- context,
- layout,
- world,
- item,
- icon,
- active_data,
- active_texture_index,
- index,
- ):
- world = context.world # .pov
- active_data = world.pov
- # tex = context.texture #may be needed later?
-
- # We could write some code to decide which icon to use here...
- custom_icon = 'TEXTURE'
-
- # Make sure your code supports all 3 layout types
- if self.layout_type in {'DEFAULT', 'COMPACT'}:
- layout.label(item.name, icon=custom_icon)
-
- elif self.layout_type in {'GRID'}:
- layout.alignment = 'CENTER'
- layout.label("", icon=custom_icon)
-
-
-class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(bpy.types.UIList):
+class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(UIList):
"""Use this class to show pov texture slots list."""
# texture_slots:
@@ -2304,6 +2395,53 @@ class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(bpy.types.UIList):
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
+# Rewrite an existing class to modify.
+# register but not unregistered because
+# the modified parts concern only POVRAY_RENDER
+class TEXTURE_PT_context(TextureButtonsPanel, Panel):
+ bl_label = ""
+ bl_context = "texture"
+ bl_options = {'HIDE_HEADER'}
+ COMPAT_ENGINES = {'POVRAY_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
+
+ @classmethod
+ def poll(cls, context):
+ return (
+ (context.scene.texture_context
+ not in('MATERIAL','WORLD','LIGHT','PARTICLES','LINESTYLE')
+ or context.scene.render.engine != 'POVRAY_RENDER')
+ )
+ def draw(self, context):
+ layout = self.layout
+ tex = context.texture
+ space = context.space_data
+ pin_id = space.pin_id
+ use_pin_id = space.use_pin_id
+ user = context.texture_user
+
+ col = layout.column()
+
+ if not (use_pin_id and isinstance(pin_id, bpy.types.Texture)):
+ pin_id = None
+
+ if not pin_id:
+ col.template_texture_user()
+
+ if user or pin_id:
+ col.separator()
+
+ if pin_id:
+ col.template_ID(space, "pin_id")
+ else:
+ propname = context.texture_user_property.identifier
+ col.template_ID(user, propname, new="texture.new")
+
+ if tex:
+ col.separator()
+
+ split = col.split(factor=0.2)
+ split.label(text="Type")
+ split.prop(tex, "type", text="")
class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel):
"""Use this class to show pov texture context buttons."""
@@ -2316,11 +2454,11 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel):
def poll(cls, context):
engine = context.scene.render.engine
return engine in cls.COMPAT_ENGINES
- # if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")):
+ # if not (hasattr(context, "pov_texture_slot") or hasattr(context, "texture_node")):
# return False
return (
context.material
- or context.world
+ or context.scene.world
or context.light
or context.texture
or context.line_style
@@ -2333,11 +2471,12 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel):
layout = self.layout
scene = context.scene
+ mat = context.view_layer.objects.active.active_material
+ wld = context.scene.world
+
layout.prop(scene, "texture_context", expand=True)
- if scene.texture_context == 'MATERIAL':
- mat = context.scene.view_layers[
- "View Layer"
- ].objects.active.active_material
+ if scene.texture_context == 'MATERIAL' and mat is not None:
+
row = layout.row()
row.template_list(
"MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist",
@@ -2353,22 +2492,90 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel):
col = row.column(align=True)
col.operator("pov.textureslotadd", icon='ADD', text='')
col.operator("pov.textureslotremove", icon='REMOVE', text='')
+ #todo: recreate for pov_texture_slots?
+ #col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
+ #col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
col.separator()
if mat.pov_texture_slots:
index = mat.pov.active_texture_index
slot = mat.pov_texture_slots[index]
- povtex = slot.name
+ povtex = slot.texture#slot.name
tex = bpy.data.textures[povtex]
col.prop(tex, 'use_fake_user', text='')
- layout.label(text='Find texture:')
+ #layout.label(text='Linked Texture data browser:')
+ propname = slot.texture_search
+ # if slot.texture was a pointer to texture data rather than just a name string:
+ # layout.template_ID(povtex, "texture", new="texture.new")
+
layout.prop_search(
- slot, 'texture_search', bpy.data, 'textures', text=''
+ slot, 'texture_search', bpy.data, 'textures', text='', icon='TEXTURE'
)
+ try:
+ bpy.context.tool_settings.image_paint.brush.texture = bpy.data.textures[slot.texture_search]
+ bpy.context.tool_settings.image_paint.brush.mask_texture = bpy.data.textures[slot.texture_search]
+ except KeyError:
+ # texture not hand-linked by user
+ pass
+
+ if tex:
+ layout.separator()
+ split = layout.split(factor=0.2)
+ split.label(text="Type")
+ split.prop(tex, "type", text="")
+
# else:
# for i in range(18): # length of material texture slots
# mat.pov_texture_slots.add()
+ elif scene.texture_context == 'WORLD' and wld is not None:
+ row = layout.row()
+ row.template_list(
+ "WORLD_TEXTURE_SLOTS_UL_POV_layerlist",
+ "",
+ wld,
+ "pov_texture_slots",
+ wld.pov,
+ "active_texture_index",
+ rows=2,
+ maxrows=16,
+ type="DEFAULT"
+ )
+ col = row.column(align=True)
+ col.operator("pov.textureslotadd", icon='ADD', text='')
+ col.operator("pov.textureslotremove", icon='REMOVE', text='')
+
+ #todo: recreate for pov_texture_slots?
+ #col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
+ #col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
+ col.separator()
+
+ if wld.pov_texture_slots:
+ index = wld.pov.active_texture_index
+ slot = wld.pov_texture_slots[index]
+ povtex = slot.texture#slot.name
+ tex = bpy.data.textures[povtex]
+ col.prop(tex, 'use_fake_user', text='')
+ #layout.label(text='Linked Texture data browser:')
+ propname = slot.texture_search
+ # if slot.texture was a pointer to texture data rather than just a name string:
+ # layout.template_ID(povtex, "texture", new="texture.new")
+
+ layout.prop_search(
+ slot, 'texture_search', bpy.data, 'textures', text='', icon='TEXTURE'
+ )
+ try:
+ bpy.context.tool_settings.image_paint.brush.texture = bpy.data.textures[slot.texture_search]
+ bpy.context.tool_settings.image_paint.brush.mask_texture = bpy.data.textures[slot.texture_search]
+ except KeyError:
+ # texture not hand-linked by user
+ pass
+
+ if tex:
+ layout.separator()
+ split = layout.split(factor=0.2)
+ split.label(text="Type")
+ split.prop(tex, "type", text="")
# Commented out below is a reminder of what existed in Blender Internal
# attributes need to be recreated
@@ -2518,7 +2725,7 @@ class TEXTURE_PT_colors(TextureButtonsPanel, Panel):
# Texture Slot Panels #
-class MATERIAL_OT_POV_texture_slot_add(Operator):
+class TEXTURE_OT_POV_texture_slot_add(Operator):
"""Use this class for the add texture slot button."""
bl_idname = "pov.textureslotadd"
@@ -2528,18 +2735,29 @@ class MATERIAL_OT_POV_texture_slot_add(Operator):
COMPAT_ENGINES = {'POVRAY_RENDER'}
def execute(self, context):
-
+ idblock = pov_context_tex_datablock(context)
tex = bpy.data.textures.new(name='Texture', type='IMAGE')
- tex.use_fake_user = True
- ob = context.scene.view_layers["View Layer"].objects.active
- slot = ob.active_material.pov_texture_slots.add()
+ #tex.use_fake_user = True
+ #mat = context.view_layer.objects.active.active_material
+ slot = idblock.pov_texture_slots.add()
slot.name = tex.name
slot.texture = tex.name
+ slot.texture_search = tex.name
+ # Switch paint brush and paint brush mask
+ # to this texture so settings remain contextual
+ bpy.context.tool_settings.image_paint.brush.texture = tex
+ bpy.context.tool_settings.image_paint.brush.mask_texture = tex
+ idblock.pov.active_texture_index = (len(idblock.pov_texture_slots)-1)
+
+ #for area in bpy.context.screen.areas:
+ #if area.type in ['PROPERTIES']:
+ #area.tag_redraw()
+
return {'FINISHED'}
-class MATERIAL_OT_POV_texture_slot_remove(Operator):
+class TEXTURE_OT_POV_texture_slot_remove(Operator):
"""Use this class for the remove texture slot button."""
bl_idname = "pov.textureslotremove"
@@ -2549,14 +2767,23 @@ class MATERIAL_OT_POV_texture_slot_remove(Operator):
COMPAT_ENGINES = {'POVRAY_RENDER'}
def execute(self, context):
- pass
- # tex = bpy.data.textures.new()
- # tex_slot = context.object.active_material.pov_texture_slots.add()
- # tex_slot.name = tex.name
+ idblock = pov_context_tex_datablock(context)
+ #mat = context.view_layer.objects.active.active_material
+ tex_slot = idblock.pov_texture_slots.remove(idblock.pov.active_texture_index)
+ if idblock.pov.active_texture_index > 0:
+ idblock.pov.active_texture_index -= 1
+ try:
+ tex = idblock.pov_texture_slots[idblock.pov.active_texture_index].texture
+ except IndexError:
+ # No more slots
+ return {'FINISHED'}
+ # Switch paint brush to previous texture so settings remain contextual
+ # if 'tex' in locals(): # Would test is the tex variable is assigned / exists
+ bpy.context.tool_settings.image_paint.brush.texture = bpy.data.textures[tex]
+ bpy.context.tool_settings.image_paint.brush.mask_texture = bpy.data.textures[tex]
return {'FINISHED'}
-
class TextureSlotPanel(TextureButtonsPanel):
"""Use this class to show pov texture slots panel."""
@@ -2586,7 +2813,7 @@ class TEXTURE_PT_POV_type(TextureButtonsPanel, Panel):
tex = context.texture
split = layout.split(factor=0.2)
- split.label(text="POV:")
+ split.label(text="Pattern")
split.prop(tex.pov, "tex_pattern_type", text="")
# row = layout.row()
@@ -2631,6 +2858,7 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel):
"""Use this class to define pov texture pattern buttons."""
bl_label = "POV Pattern Options"
+ bl_options = {'HIDE_HEADER'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
def draw(self, context):
@@ -2911,6 +3139,112 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel):
row.prop(tex.pov, "warp_turbulence_z", text="Z")
row.prop(tex.pov, "modifier_omega", text="Omega")
+class TEXTURE_PT_POV_mapping(TextureSlotPanel, Panel):
+ """Use this class to define POV texture mapping buttons"""
+ bl_label = "Mapping"
+ COMPAT_ENGINES = {'POVRAY_RENDER'}
+ bl_space_type = 'PROPERTIES'
+ bl_region_type = 'WINDOW'
+
+ @classmethod
+ def poll(cls, context):
+ idblock = pov_context_tex_datablock(context)
+ if isinstance(idblock, Brush) and not context.sculpt_object:
+ return False
+
+ if not getattr(context, "texture_slot", None):
+ return False
+
+ engine = context.scene.render.engine
+ return (engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+
+ idblock = pov_context_tex_datablock(context)
+
+ #tex = context.texture_slot
+ tex = mat.pov_texture_slots[
+ mat.active_texture_index
+ ]
+ if not isinstance(idblock, Brush):
+ split = layout.split(percentage=0.3)
+ col = split.column()
+ col.label(text="Coordinates:")
+ col = split.column()
+ col.prop(tex, "texture_coords", text="")
+
+ if tex.texture_coords == 'ORCO':
+ """
+ ob = context.object
+ if ob and ob.type == 'MESH':
+ split = layout.split(percentage=0.3)
+ split.label(text="Mesh:")
+ split.prop(ob.data, "texco_mesh", text="")
+ """
+ elif tex.texture_coords == 'UV':
+ split = layout.split(percentage=0.3)
+ split.label(text="Map:")
+ ob = context.object
+ if ob and ob.type == 'MESH':
+ split.prop_search(tex, "uv_layer", ob.data, "uv_textures", text="")
+ else:
+ split.prop(tex, "uv_layer", text="")
+
+ elif tex.texture_coords == 'OBJECT':
+ split = layout.split(percentage=0.3)
+ split.label(text="Object:")
+ split.prop(tex, "object", text="")
+
+ elif tex.texture_coords == 'ALONG_STROKE':
+ split = layout.split(percentage=0.3)
+ split.label(text="Use Tips:")
+ split.prop(tex, "use_tips", text="")
+
+ if isinstance(idblock, Brush):
+ if context.sculpt_object or context.image_paint_object:
+ brush_texture_settings(layout, idblock, context.sculpt_object)
+ else:
+ if isinstance(idblock, FreestyleLineStyle):
+ split = layout.split(percentage=0.3)
+ split.label(text="Projection:")
+ split.prop(tex, "mapping", text="")
+
+ split = layout.split(percentage=0.3)
+ split.separator()
+ row = split.row()
+ row.prop(tex, "mapping_x", text="")
+ row.prop(tex, "mapping_y", text="")
+ row.prop(tex, "mapping_z", text="")
+
+ elif isinstance(idblock, Material):
+ split = layout.split(percentage=0.3)
+ split.label(text="Projection:")
+ split.prop(tex, "mapping", text="")
+
+ split = layout.split()
+
+ col = split.column()
+ if tex.texture_coords in {'ORCO', 'UV'}:
+ col.prop(tex, "use_from_dupli")
+ if (idblock.type == 'VOLUME' and tex.texture_coords == 'ORCO'):
+ col.prop(tex, "use_map_to_bounds")
+ elif tex.texture_coords == 'OBJECT':
+ col.prop(tex, "use_from_original")
+ if (idblock.type == 'VOLUME'):
+ col.prop(tex, "use_map_to_bounds")
+ else:
+ col.label()
+
+ col = split.column()
+ row = col.row()
+ row.prop(tex, "mapping_x", text="")
+ row.prop(tex, "mapping_y", text="")
+ row.prop(tex, "mapping_z", text="")
+
+ row = layout.row()
+ row.column().prop(tex, "offset")
+ row.column().prop(tex, "scale")
class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel):
"""Use this class to define pov texture influence buttons."""
@@ -2919,18 +3253,20 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel):
COMPAT_ENGINES = {'POVRAY_RENDER'}
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
- # bl_context = 'texture'
+ #bl_context = 'texture'
@classmethod
def poll(cls, context):
idblock = pov_context_tex_datablock(context)
if (
- isinstance(idblock, Brush)
- and bpy.context.scene.texture_context == 'OTHER'
+ # isinstance(idblock, Brush) and # Brush used for everything since 2.8
+ context.scene.texture_context == 'OTHER'
): # XXX replace by isinstance(idblock, bpy.types.Brush) and ...
return False
- # if not getattr(context, "pov_texture_slot", None):
- # return False
+ # Specify below also for pov_world_texture_slots, lights etc.
+ # to display for various types of slots but only when any
+ if not getattr(idblock, "pov_texture_slots", None):
+ return False
engine = context.scene.render.engine
return engine in cls.COMPAT_ENGINES
@@ -2940,14 +3276,13 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel):
layout = self.layout
idblock = pov_context_tex_datablock(context)
-
# tex = context.pov_texture_slot
- mat = bpy.context.active_object.active_material
- texslot = mat.pov_texture_slots[
- mat.active_texture_index
+ #mat = bpy.context.active_object.active_material
+ texslot = idblock.pov_texture_slots[
+ idblock.pov.active_texture_index
] # bpy.data.textures[mat.active_texture_index]
tex = bpy.data.textures[
- mat.pov_texture_slots[mat.active_texture_index].texture
+ idblock.pov_texture_slots[idblock.pov.active_texture_index].texture
]
def factor_but(layout, toggle, factor, name):
@@ -3756,7 +4091,7 @@ class OBJECT_PT_povray_replacement_text(ObjectButtonsPanel, Panel):
###############################################################################
-class VIEW_MT_POV_primitives_add(bpy.types.Menu):
+class VIEW_MT_POV_primitives_add(Menu):
"""Define the primitives menu with presets"""
bl_idname = "VIEW_MT_POV_primitives_add"
@@ -3777,7 +4112,7 @@ class VIEW_MT_POV_primitives_add(bpy.types.Menu):
layout.menu(VIEW_MT_POV_import.bl_idname, text="Import", icon="IMPORT")
-class VIEW_MT_POV_Basic_Shapes(bpy.types.Menu):
+class VIEW_MT_POV_Basic_Shapes(Menu):
"""Use this class to sort simple primitives menu entries."""
bl_idname = "POVRAY_MT_basic_shape_tools"
@@ -3859,7 +4194,7 @@ class VIEW_MT_POV_Basic_Shapes(bpy.types.Menu):
)
-class VIEW_MT_POV_import(bpy.types.Menu):
+class VIEW_MT_POV_import(Menu):
"""Use this class for the import menu."""
bl_idname = "POVRAY_MT_import_tools"
@@ -3910,7 +4245,7 @@ def menu_func_import(self, context):
# return True
-class NODE_MT_POV_map_create(bpy.types.Menu):
+class NODE_MT_POV_map_create(Menu):
"""Create maps"""
bl_idname = "POVRAY_MT_node_map_create"
@@ -4056,7 +4391,7 @@ def validinsert(ext):
return ext in {".txt", ".inc", ".pov"}
-class TEXT_MT_POV_insert(bpy.types.Menu):
+class TEXT_MT_POV_insert(Menu):
"""Use this class to create a menu launcher in text editor for the TEXT_OT_POV_insert operator ."""
bl_label = "Insert"
@@ -4116,10 +4451,10 @@ class TEXT_PT_POV_custom_code(TextButtonsPanel, Panel):
row = box.row()
row.prop(text.pov, "custom_code", expand=True)
if text.pov.custom_code in {'3dview'}:
- box.operator("render.render", icon='OUTLINER_DATA_POSE')
+ box.operator("render.render", icon='OUTLINER_DATA_ARMATURE')
if text.pov.custom_code in {'text'}:
rtext = bpy.context.space_data.text
- box.operator("text.run", icon='POSE_DATA')
+ box.operator("text.run", icon='ARMATURE_DATA')
# layout.prop(text.pov, "custom_code")
elif text.pov.custom_code in {'both'}:
box.operator("render.render", icon='POSE_HLT')
@@ -4133,7 +4468,7 @@ class TEXT_PT_POV_custom_code(TextButtonsPanel, Panel):
# Text editor templates from header menu
-class TEXT_MT_POV_templates(bpy.types.Menu):
+class TEXT_MT_POV_templates(Menu):
"""Use this class to create a menu for the same pov templates scenes as other pov IDEs."""
bl_label = "POV"
@@ -4154,12 +4489,111 @@ def menu_func_templates(self, context):
# Do not depend on POV being active renderer here...
self.layout.menu("TEXT_MT_POV_templates")
+###############################################################################
+# Freestyle
+###############################################################################
+#import addon_utils
+#addon_utils.paths()[0]
+#addon_utils.modules()
+#mod.bl_info['name'] == 'Freestyle SVG Exporter':
+bpy.utils.script_paths("addons")
+#render_freestyle_svg = os.path.join(bpy.utils.script_paths("addons"), "render_freestyle_svg.py")
+
+render_freestyle_svg = bpy.context.preferences.addons.get('render_freestyle_svg')
+ #mpath=addon_utils.paths()[0].render_freestyle_svg
+ #import mpath
+ #from mpath import render_freestyle_svg #= addon_utils.modules(['Freestyle SVG Exporter'])
+ #from scripts\\addons import render_freestyle_svg
+if check_render_freestyle_svg():
+ '''
+ snippetsWIP
+ import myscript
+ import importlib
+
+ importlib.reload(myscript)
+ myscript.main()
+ '''
+ for member in dir(render_freestyle_svg):
+ subclass = getattr(render_freestyle_svg, member)
+ try:
+ subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
+ if subclass.bl_idname == "RENDER_PT_SVGExporterPanel":
+ subclass.bl_parent_id = "RENDER_PT_POV_filter"
+ subclass.bl_options = {'HIDE_HEADER'}
+ #subclass.bl_order = 11
+ print(subclass.bl_info)
+ except:
+ pass
+
+ #del render_freestyle_svg.RENDER_PT_SVGExporterPanel.bl_parent_id
+
+
+class RENDER_PT_POV_filter(RenderButtonsPanel, Panel):
+ """Use this class to invoke stuff like Freestyle UI."""
+
+ bl_label = "Freestyle"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'POVRAY_RENDER'}
+
+ @classmethod
+ def poll(cls, context):
+ with_freestyle = bpy.app.build_options.freestyle
+ engine = context.scene.render.engine
+ return(with_freestyle and engine == 'POVRAY_RENDER')
+ def draw_header(self, context):
+
+ #scene = context.scene
+ rd = context.scene.render
+ layout = self.layout
+
+ if rd.use_freestyle:
+ layout.prop(
+ rd, "use_freestyle", text="", icon='LINE_DATA'
+ )
+
+ else:
+ layout.prop(
+ rd, "use_freestyle", text="", icon='OUTLINER_OB_IMAGE'
+ )
+
+ def draw(self, context):
+ rd = context.scene.render
+ layout = self.layout
+ layout.active = rd.use_freestyle
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+ flow = layout.grid_flow(
+ row_major=True,
+ columns=0,
+ even_columns=True,
+ even_rows=False,
+ align=True,
+ )
+
+ flow.prop(rd, "line_thickness_mode", expand=True)
+
+ if rd.line_thickness_mode == 'ABSOLUTE':
+ flow.prop(rd, "line_thickness")
+
+ # Warning if the Freestyle SVG Exporter addon is not enabled
+ if not check_render_freestyle_svg():
+ # col = box.column()
+ layout.label(
+ text="Please enable Freestyle SVG Exporter addon", icon="INFO"
+ )
+ # layout.separator()
+ layout.operator(
+ "preferences.addon_show",
+ text="Go to Render: Freestyle SVG Exporter addon",
+ icon="PREFERENCES",
+ ).module = "render_freestyle_svg"
classes = (
WORLD_PT_POV_world,
WORLD_MT_POV_presets,
WORLD_OT_POV_add_preset,
- WORLD_TEXTURE_SLOTS_UL_List,
+ WORLD_TEXTURE_SLOTS_UL_POV_layerlist,
+ #WORLD_TEXTURE_SLOTS_UL_List,
WORLD_PT_POV_mist,
# RenderButtonsPanel,
# ModifierButtonsPanel,
@@ -4188,6 +4622,7 @@ classes = (
RENDER_PT_POV_photons,
RENDER_PT_POV_antialias,
RENDER_PT_POV_radiosity,
+ RENDER_PT_POV_filter,
POV_RADIOSITY_MT_presets,
RENDER_OT_POV_radiosity_add_preset,
RENDER_PT_POV_media,
@@ -4232,13 +4667,13 @@ classes = (
TEXT_MT_POV_insert,
TEXT_PT_POV_custom_code,
TEXT_MT_POV_templates,
- # TEXTURE_PT_context,
- # TEXTURE_PT_POV_povray_texture_slots,
- TEXTURE_UL_POV_texture_slots,
+ #TEXTURE_PT_POV_povray_texture_slots,
+ #TEXTURE_UL_POV_texture_slots,
MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist,
- MATERIAL_OT_POV_texture_slot_add,
- MATERIAL_OT_POV_texture_slot_remove,
+ TEXTURE_OT_POV_texture_slot_add,
+ TEXTURE_OT_POV_texture_slot_remove,
TEXTURE_PT_POV_influence,
+ TEXTURE_PT_POV_mapping,
)
@@ -4257,11 +4692,18 @@ def register():
# was used for parametric objects but made the other addon unreachable on
# unregister for other tools to use created a user action call instead
# addon_utils.enable("add_mesh_extra_objects", default_set=False, persistent=True)
-
# bpy.types.TEXTURE_PT_context_texture.prepend(TEXTURE_PT_POV_type)
+ if not povCentricWorkspace in bpy.app.handlers.load_post:
+ print("Adding POV wentric workspace on load handlers list")
+ bpy.app.handlers.load_post.append(povCentricWorkspace)
def unregister():
+ if povCentricWorkspace in bpy.app.handlers.load_post:
+ print("Removing POV wentric workspace from load handlers list")
+ bpy.app.handlers.load_post.remove(povCentricWorkspace)
+
+
# from bpy.utils import unregister_class
# bpy.types.TEXTURE_PT_context_texture.remove(TEXTURE_PT_POV_type)
@@ -4274,4 +4716,5 @@ def unregister():
bpy.types.VIEW3D_MT_add.remove(menu_func_add)
for cls in reversed(classes):
- unregister_class(cls)
+ if cls != TEXTURE_PT_context:
+ unregister_class(cls)