mirror of
https://github.com/blender/blender-addons.git
synced 2025-08-20 13:22:58 +00:00
1285 lines
50 KiB
Python
Executable File
1285 lines
50 KiB
Python
Executable File
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
"""User interface for texturing tools."""
|
|
|
|
import bpy
|
|
from bpy.utils import register_class, unregister_class
|
|
from bpy.types import (
|
|
Operator,
|
|
Menu,
|
|
UIList,
|
|
Panel,
|
|
Brush,
|
|
Material,
|
|
Light,
|
|
World,
|
|
ParticleSettings,
|
|
FreestyleLineStyle,
|
|
)
|
|
|
|
# from .ui import TextureButtonsPanel
|
|
|
|
from .shading_properties import pov_context_tex_datablock
|
|
from bl_ui.properties_paint_common import brush_texture_settings
|
|
|
|
# Example of wrapping every class 'as is'
|
|
from bl_ui import properties_texture
|
|
|
|
# unused, replaced by pov_context_tex_datablock (no way to use?):
|
|
# from bl_ui.properties_texture import context_tex_datablock
|
|
# from bl_ui.properties_texture import texture_filter_common #unused yet?
|
|
|
|
for member in dir(properties_texture):
|
|
subclass = getattr(properties_texture, member)
|
|
if hasattr(subclass, "COMPAT_ENGINES"):
|
|
subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
|
|
del properties_texture
|
|
|
|
|
|
class TextureButtonsPanel:
|
|
"""Use this class to define buttons from the texture tab properties."""
|
|
|
|
bl_space_type = "PROPERTIES"
|
|
bl_region_type = "WINDOW"
|
|
bl_context = "texture"
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
tex = context.texture
|
|
rd = context.scene.render
|
|
return tex and (rd.engine in cls.COMPAT_ENGINES)
|
|
|
|
|
|
class TEXTURE_MT_POV_specials(Menu):
|
|
"""Use this class to define pov texture slot operations buttons."""
|
|
|
|
bl_label = "Texture Specials"
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.operator("texture.slot_copy", icon="COPYDOWN")
|
|
layout.operator("texture.slot_paste", icon="PASTEDOWN")
|
|
|
|
|
|
class WORLD_TEXTURE_SLOTS_UL_POV_layerlist(UIList):
|
|
"""Use this class to show pov texture slots list."""
|
|
|
|
index: bpy.props.IntProperty(name="index")
|
|
# should active_propname be index or..?
|
|
|
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
|
# world = context.scene.world # .pov # NOT USED
|
|
# active_data = world.pov # NOT USED
|
|
# 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
|
|
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
|
|
if self.layout_type in {"DEFAULT", "COMPACT"}:
|
|
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
|
|
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
|
|
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
|
|
# Note "data" names should never be translated!
|
|
if slot:
|
|
layout.prop(slot, "texture", text="", emboss=False, icon="TEXTURE")
|
|
else:
|
|
layout.label(text="New", translate=False, icon_value=icon)
|
|
# 'GRID' layout type should be as compact as possible (typically a single icon!).
|
|
elif self.layout_type in {"GRID"}:
|
|
layout.alignment = "CENTER"
|
|
layout.label(text="", icon_value=icon)
|
|
|
|
|
|
class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(UIList):
|
|
"""Use this class to show pov texture slots list."""
|
|
|
|
# texture_slots:
|
|
index: bpy.props.IntProperty(name="index")
|
|
# foo = random prop
|
|
|
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
|
# ob = data
|
|
slot = item
|
|
# ma = slot.name
|
|
# draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code.
|
|
if self.layout_type in {"DEFAULT", "COMPACT"}:
|
|
# You should always start your row layout by a label (icon + text), or a non-embossed text field,
|
|
# this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
|
|
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
|
|
# Note "data" names should never be translated!
|
|
if slot:
|
|
layout.prop(slot, "texture", text="", emboss=False, icon="TEXTURE")
|
|
else:
|
|
layout.label(text="New", translate=False, icon_value=icon)
|
|
# 'GRID' layout type should be as compact as possible (typically a single icon!).
|
|
elif self.layout_type in {"GRID"}:
|
|
layout.alignment = "CENTER"
|
|
layout.label(text="", icon_value=icon)
|
|
|
|
|
|
class TEXTURE_PT_context(TextureButtonsPanel, Panel):
|
|
"""Rewrite of this existing class to modify it."""
|
|
|
|
bl_label = ""
|
|
bl_context = "texture"
|
|
bl_options = {"HIDE_HEADER"}
|
|
COMPAT_ENGINES = {"POVRAY_RENDER", "BLENDER_EEVEE", "BLENDER_WORKBENCH"}
|
|
# register but not unregistered because
|
|
# the modified parts concern only POVRAY_RENDER
|
|
|
|
@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."""
|
|
|
|
bl_label = ""
|
|
bl_options = {"HIDE_HEADER"}
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
engine = context.scene.render.engine
|
|
# if not (hasattr(context, "pov_texture_slot") or hasattr(context, "texture_node")):
|
|
# return False
|
|
return (
|
|
context.material
|
|
or context.scene.world
|
|
or context.light
|
|
or context.texture
|
|
or context.line_style
|
|
or context.particle_system
|
|
or isinstance(context.space_data.pin_id, ParticleSettings)
|
|
or context.texture_user
|
|
) and (engine in cls.COMPAT_ENGINES)
|
|
|
|
def draw(self, context):
|
|
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" and mat is not None:
|
|
|
|
row = layout.row()
|
|
row.template_list(
|
|
"MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist",
|
|
"",
|
|
mat,
|
|
"pov_texture_slots",
|
|
mat.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="")
|
|
# XXX 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]
|
|
try:
|
|
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")
|
|
except KeyError:
|
|
tex = None
|
|
row = layout.row(align=True)
|
|
row.prop_search(
|
|
slot, "texture_search", bpy.data, "textures", text="", icon="TEXTURE"
|
|
)
|
|
|
|
row.operator("pov.textureslotupdate", icon="FILE_REFRESH", text="")
|
|
# 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 # NOT USED
|
|
# 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="")
|
|
|
|
|
|
class TEXTURE_OT_POV_context_texture_update(Operator):
|
|
"""Use this class for the texture slot update button."""
|
|
|
|
bl_idname = "pov.textureslotupdate"
|
|
bl_label = "Update"
|
|
bl_description = "Update texture_slot"
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
engine = context.scene.render.engine
|
|
mate = context.view_layer.objects.active.active_material
|
|
return mate and engine in cls.COMPAT_ENGINES
|
|
|
|
def execute(self, context):
|
|
# tex.use_fake_user = True
|
|
mat = context.view_layer.objects.active.active_material
|
|
index = mat.pov.active_texture_index
|
|
slot = mat.pov_texture_slots[index]
|
|
povtex = slot.texture # slot.name
|
|
tex = bpy.data.textures[povtex]
|
|
|
|
# Switch paint brush and paint brush mask
|
|
# to this texture so settings remain contextual
|
|
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
|
|
]
|
|
|
|
return {"FINISHED"}
|
|
|
|
|
|
# Commented out below is a reminder of what existed in Blender Internal
|
|
# attributes need to be recreated
|
|
"""
|
|
slot = getattr(context, "texture_slot", None)
|
|
node = getattr(context, "texture_node", None)
|
|
space = context.space_data
|
|
|
|
#attempt at replacing removed space_data
|
|
mtl = getattr(context, "material", None)
|
|
if mtl != None:
|
|
spacedependant = mtl
|
|
wld = getattr(context, "world", None)
|
|
if wld != None:
|
|
spacedependant = wld
|
|
lgt = getattr(context, "light", None)
|
|
if lgt != None:
|
|
spacedependant = lgt
|
|
|
|
|
|
#idblock = context.particle_system.settings
|
|
|
|
tex = getattr(context, "texture", None)
|
|
if tex != None:
|
|
spacedependant = tex
|
|
|
|
|
|
|
|
scene = context.scene
|
|
idblock = scene.pov#pov_context_tex_datablock(context)
|
|
pin_id = space.pin_id
|
|
|
|
#spacedependant.use_limited_texture_context = True
|
|
|
|
if space.use_pin_id and not isinstance(pin_id, Texture):
|
|
idblock = id_tex_datablock(pin_id)
|
|
pin_id = None
|
|
|
|
if not space.use_pin_id:
|
|
layout.row().prop(spacedependant, "texture_context", expand=True)
|
|
pin_id = None
|
|
|
|
if spacedependant.texture_context == 'OTHER':
|
|
if not pin_id:
|
|
layout.template_texture_user()
|
|
user = context.texture_user
|
|
if user or pin_id:
|
|
layout.separator()
|
|
|
|
row = layout.row()
|
|
|
|
if pin_id:
|
|
row.template_ID(space, "pin_id")
|
|
else:
|
|
propname = context.texture_user_property.identifier
|
|
row.template_ID(user, propname, new="texture.new")
|
|
|
|
if tex:
|
|
split = layout.split(factor=0.2)
|
|
if tex.use_nodes:
|
|
if slot:
|
|
split.label(text="Output:")
|
|
split.prop(slot, "output_node", text="")
|
|
else:
|
|
split.label(text="Type:")
|
|
split.prop(tex, "type", text="")
|
|
return
|
|
|
|
tex_collection = (pin_id is None) and (node is None) and (spacedependant.texture_context not in ('LINESTYLE','OTHER'))
|
|
|
|
if tex_collection:
|
|
|
|
pov = getattr(context, "pov", None)
|
|
active_texture_index = getattr(spacedependant, "active_texture_index", None)
|
|
print (pov)
|
|
print(idblock)
|
|
print(active_texture_index)
|
|
row = layout.row()
|
|
|
|
row.template_list("TEXTURE_UL_texslots", "", idblock, "texture_slots",
|
|
idblock, "active_texture_index", rows=2, maxrows=16, type="DEFAULT")
|
|
|
|
# row.template_list("WORLD_TEXTURE_SLOTS_UL_List", "texture_slots", world,
|
|
# world.texture_slots, world, "active_texture_index", rows=2)
|
|
|
|
col = row.column(align=True)
|
|
col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
|
|
col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
|
|
col.menu("TEXTURE_MT_POV_specials", icon='DOWNARROW_HLT', text="")
|
|
|
|
if tex_collection:
|
|
layout.template_ID(idblock, "active_texture", new="texture.new")
|
|
elif node:
|
|
layout.template_ID(node, "texture", new="texture.new")
|
|
elif idblock:
|
|
layout.template_ID(idblock, "texture", new="texture.new")
|
|
|
|
if pin_id:
|
|
layout.template_ID(space, "pin_id")
|
|
|
|
if tex:
|
|
split = layout.split(factor=0.2)
|
|
if tex.use_nodes:
|
|
if slot:
|
|
split.label(text="Output:")
|
|
split.prop(slot, "output_node", text="")
|
|
else:
|
|
split.label(text="Type:")
|
|
"""
|
|
|
|
|
|
class TEXTURE_PT_colors(TextureButtonsPanel, Panel):
|
|
"""Use this class to show pov color ramps."""
|
|
|
|
bl_label = "Colors"
|
|
bl_options = {"DEFAULT_CLOSED"}
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
tex = context.texture
|
|
|
|
layout.prop(tex, "use_color_ramp", text="Ramp")
|
|
if tex.use_color_ramp:
|
|
layout.template_color_ramp(tex, "color_ramp", expand=True)
|
|
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
col.label(text="RGB Multiply:")
|
|
sub = col.column(align=True)
|
|
sub.prop(tex, "factor_red", text="R")
|
|
sub.prop(tex, "factor_green", text="G")
|
|
sub.prop(tex, "factor_blue", text="B")
|
|
|
|
col = split.column()
|
|
col.label(text="Adjust:")
|
|
col.prop(tex, "intensity")
|
|
col.prop(tex, "contrast")
|
|
col.prop(tex, "saturation")
|
|
|
|
col = layout.column()
|
|
col.prop(tex, "use_clamp", text="Clamp")
|
|
|
|
|
|
# Texture Slot Panels #
|
|
|
|
|
|
class TEXTURE_OT_POV_texture_slot_add(Operator):
|
|
"""Use this class for the add texture slot button."""
|
|
|
|
bl_idname = "pov.textureslotadd"
|
|
bl_label = "Add"
|
|
bl_description = "Add texture_slot"
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
def execute(self, context):
|
|
idblock = pov_context_tex_datablock(context)
|
|
slot_brush = bpy.data.brushes.new("POVtextureSlot")
|
|
context.tool_settings.image_paint.brush = slot_brush
|
|
tex = bpy.data.textures.new(name="Texture", type="IMAGE")
|
|
# 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 TEXTURE_OT_POV_texture_slot_remove(Operator):
|
|
"""Use this class for the remove texture slot button."""
|
|
|
|
bl_idname = "pov.textureslotremove"
|
|
bl_label = "Remove"
|
|
bl_description = "Remove texture_slot"
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
def execute(self, context):
|
|
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) # not used
|
|
# tex_to_delete = context.tool_settings.image_paint.brush.texture
|
|
# bpy.data.textures.remove(tex_to_delete, do_unlink=True, do_id_user=True, do_ui_user=True)
|
|
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."""
|
|
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
if not hasattr(context, "pov_texture_slot"):
|
|
return False
|
|
|
|
engine = context.scene.render.engine
|
|
# return TextureButtonsPanel.poll(cls, context) and (engine in cls.COMPAT_ENGINES)
|
|
return TextureButtonsPanel.poll(context) and (engine in cls.COMPAT_ENGINES)
|
|
|
|
|
|
class TEXTURE_PT_POV_type(TextureButtonsPanel, Panel):
|
|
"""Use this class to define pov texture type buttons."""
|
|
|
|
bl_label = "POV Textures"
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
bl_options = {"HIDE_HEADER"}
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
# world = context.world # unused
|
|
tex = context.texture
|
|
|
|
split = layout.split(factor=0.2)
|
|
split.label(text="Pattern")
|
|
split.prop(tex.pov, "tex_pattern_type", text="")
|
|
|
|
# row = layout.row()
|
|
# row.template_list("WORLD_TEXTURE_SLOTS_UL_List", "texture_slots", world,
|
|
# world.texture_slots, world, "active_texture_index")
|
|
|
|
|
|
class TEXTURE_PT_POV_preview(TextureButtonsPanel, Panel):
|
|
"""Use this class to define pov texture preview panel."""
|
|
|
|
bl_label = "Preview"
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
bl_options = {"HIDE_HEADER"}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
engine = context.scene.render.engine
|
|
if not hasattr(context, "pov_texture_slot"):
|
|
return False
|
|
tex = context.texture
|
|
# mat = bpy.context.active_object.active_material #unused
|
|
return tex and (tex.pov.tex_pattern_type != "emulator") and (engine in cls.COMPAT_ENGINES)
|
|
|
|
def draw(self, context):
|
|
tex = context.texture
|
|
slot = getattr(context, "pov_texture_slot", None)
|
|
# idblock = pov_context_tex_datablock(context) # unused
|
|
layout = self.layout
|
|
# if idblock:
|
|
# layout.template_preview(tex, parent=idblock, slot=slot)
|
|
if tex.pov.tex_pattern_type != "emulator":
|
|
layout.operator("tex.preview_update")
|
|
else:
|
|
layout.template_preview(tex, slot=slot)
|
|
|
|
|
|
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):
|
|
# mat = bpy.context.active_object.active_material # Unused
|
|
tex = context.texture
|
|
if tex is not None and tex.pov.tex_pattern_type != "emulator":
|
|
layout = self.layout
|
|
if tex.pov.tex_pattern_type == "agate":
|
|
layout.prop(tex.pov, "modifier_turbulence", text="Agate Turbulence")
|
|
if tex.pov.tex_pattern_type in {"spiral1", "spiral2"}:
|
|
layout.prop(tex.pov, "modifier_numbers", text="Number of arms")
|
|
if tex.pov.tex_pattern_type == "tiling":
|
|
layout.prop(tex.pov, "modifier_numbers", text="Pattern number")
|
|
if tex.pov.tex_pattern_type == "magnet":
|
|
layout.prop(tex.pov, "magnet_style", text="Magnet style")
|
|
align = True
|
|
if tex.pov.tex_pattern_type == "quilted":
|
|
row = layout.row(align=align)
|
|
row.prop(tex.pov, "modifier_control0", text="Control0")
|
|
row.prop(tex.pov, "modifier_control1", text="Control1")
|
|
if tex.pov.tex_pattern_type == "brick":
|
|
col = layout.column(align=align)
|
|
row = col.row()
|
|
row.prop(tex.pov, "brick_size_x", text="Brick size X")
|
|
row.prop(tex.pov, "brick_size_y", text="Brick size Y")
|
|
row = col.row()
|
|
row.prop(tex.pov, "brick_size_z", text="Brick size Z")
|
|
row.prop(tex.pov, "brick_mortar", text="Brick mortar")
|
|
if tex.pov.tex_pattern_type in {"julia", "mandel", "magnet"}:
|
|
col = layout.column(align=align)
|
|
if tex.pov.tex_pattern_type == "julia":
|
|
row = col.row()
|
|
row.prop(tex.pov, "julia_complex_1", text="Complex 1")
|
|
row.prop(tex.pov, "julia_complex_2", text="Complex 2")
|
|
if tex.pov.tex_pattern_type == "magnet" and tex.pov.magnet_style == "julia":
|
|
row = col.row()
|
|
row.prop(tex.pov, "julia_complex_1", text="Complex 1")
|
|
row.prop(tex.pov, "julia_complex_2", text="Complex 2")
|
|
row = col.row()
|
|
if tex.pov.tex_pattern_type in {"julia", "mandel"}:
|
|
row.prop(tex.pov, "f_exponent", text="Exponent")
|
|
if tex.pov.tex_pattern_type == "magnet":
|
|
row.prop(tex.pov, "magnet_type", text="Type")
|
|
row.prop(tex.pov, "f_iter", text="Iterations")
|
|
row = col.row()
|
|
row.prop(tex.pov, "f_ior", text="Interior")
|
|
row.prop(tex.pov, "f_ior_fac", text="Factor I")
|
|
row = col.row()
|
|
row.prop(tex.pov, "f_eor", text="Exterior")
|
|
row.prop(tex.pov, "f_eor_fac", text="Factor E")
|
|
if tex.pov.tex_pattern_type == "gradient":
|
|
layout.label(text="Gradient orientation:")
|
|
column_flow = layout.column_flow(columns=3, align=True)
|
|
column_flow.prop(tex.pov, "grad_orient_x", text="X")
|
|
column_flow.prop(tex.pov, "grad_orient_y", text="Y")
|
|
column_flow.prop(tex.pov, "grad_orient_z", text="Z")
|
|
if tex.pov.tex_pattern_type == "pavement":
|
|
layout.prop(tex.pov, "pave_sides", text="Pavement:number of sides")
|
|
col = layout.column(align=align)
|
|
column_flow = col.column_flow(columns=3, align=True)
|
|
column_flow.prop(tex.pov, "pave_tiles", text="Tiles")
|
|
if tex.pov.pave_sides == "4" and tex.pov.pave_tiles == 6:
|
|
column_flow.prop(tex.pov, "pave_pat_35", text="Pattern")
|
|
if tex.pov.pave_sides == "6" and tex.pov.pave_tiles == 5:
|
|
column_flow.prop(tex.pov, "pave_pat_22", text="Pattern")
|
|
if tex.pov.pave_sides == "4" and tex.pov.pave_tiles == 5:
|
|
column_flow.prop(tex.pov, "pave_pat_12", text="Pattern")
|
|
if tex.pov.pave_sides == "3" and tex.pov.pave_tiles == 6:
|
|
column_flow.prop(tex.pov, "pave_pat_12", text="Pattern")
|
|
if tex.pov.pave_sides == "6" and tex.pov.pave_tiles == 4:
|
|
column_flow.prop(tex.pov, "pave_pat_7", text="Pattern")
|
|
if tex.pov.pave_sides == "4" and tex.pov.pave_tiles == 4:
|
|
column_flow.prop(tex.pov, "pave_pat_5", text="Pattern")
|
|
if tex.pov.pave_sides == "3" and tex.pov.pave_tiles == 5:
|
|
column_flow.prop(tex.pov, "pave_pat_4", text="Pattern")
|
|
if tex.pov.pave_sides == "6" and tex.pov.pave_tiles == 3:
|
|
column_flow.prop(tex.pov, "pave_pat_3", text="Pattern")
|
|
if tex.pov.pave_sides == "3" and tex.pov.pave_tiles == 4:
|
|
column_flow.prop(tex.pov, "pave_pat_3", text="Pattern")
|
|
if tex.pov.pave_sides == "4" and tex.pov.pave_tiles == 3:
|
|
column_flow.prop(tex.pov, "pave_pat_2", text="Pattern")
|
|
if tex.pov.pave_sides == "6" and tex.pov.pave_tiles == 6:
|
|
column_flow.label(text="!!! 5 tiles!")
|
|
column_flow.prop(tex.pov, "pave_form", text="Form")
|
|
if tex.pov.tex_pattern_type == "function":
|
|
layout.prop(tex.pov, "func_list", text="Functions")
|
|
if tex.pov.tex_pattern_type == "function" and tex.pov.func_list != "NONE":
|
|
func = None
|
|
if tex.pov.func_list in {"f_noise3d", "f_ph", "f_r", "f_th"}:
|
|
func = 0
|
|
if tex.pov.func_list in {
|
|
"f_comma",
|
|
"f_crossed_trough",
|
|
"f_cubic_saddle",
|
|
"f_cushion",
|
|
"f_devils_curve",
|
|
"f_enneper",
|
|
"f_glob",
|
|
"f_heart",
|
|
"f_hex_x",
|
|
"f_hex_y",
|
|
"f_hunt_surface",
|
|
"f_klein_bottle",
|
|
"f_kummer_surface_v1",
|
|
"f_lemniscate_of_gerono",
|
|
"f_mitre",
|
|
"f_nodal_cubic",
|
|
"f_noise_generator",
|
|
"f_odd",
|
|
"f_paraboloid",
|
|
"f_pillow",
|
|
"f_piriform",
|
|
"f_quantum",
|
|
"f_quartic_paraboloid",
|
|
"f_quartic_saddle",
|
|
"f_sphere",
|
|
"f_steiners_roman",
|
|
"f_torus_gumdrop",
|
|
"f_umbrella",
|
|
}:
|
|
func = 1
|
|
if tex.pov.func_list in {
|
|
"f_bicorn",
|
|
"f_bifolia",
|
|
"f_boy_surface",
|
|
"f_superellipsoid",
|
|
"f_torus",
|
|
}:
|
|
func = 2
|
|
if tex.pov.func_list in {
|
|
"f_ellipsoid",
|
|
"f_folium_surface",
|
|
"f_hyperbolic_torus",
|
|
"f_kampyle_of_eudoxus",
|
|
"f_parabolic_torus",
|
|
"f_quartic_cylinder",
|
|
"f_torus2",
|
|
}:
|
|
func = 3
|
|
if tex.pov.func_list in {
|
|
"f_blob2",
|
|
"f_cross_ellipsoids",
|
|
"f_flange_cover",
|
|
"f_isect_ellipsoids",
|
|
"f_kummer_surface_v2",
|
|
"f_ovals_of_cassini",
|
|
"f_rounded_box",
|
|
"f_spikes_2d",
|
|
"f_strophoid",
|
|
}:
|
|
func = 4
|
|
if tex.pov.func_list in {
|
|
"f_algbr_cyl1",
|
|
"f_algbr_cyl2",
|
|
"f_algbr_cyl3",
|
|
"f_algbr_cyl4",
|
|
"f_blob",
|
|
"f_mesh1",
|
|
"f_poly4",
|
|
"f_spikes",
|
|
}:
|
|
func = 5
|
|
if tex.pov.func_list in {
|
|
"f_devils_curve_2d",
|
|
"f_dupin_cyclid",
|
|
"f_folium_surface_2d",
|
|
"f_hetero_mf",
|
|
"f_kampyle_of_eudoxus_2d",
|
|
"f_lemniscate_of_gerono_2d",
|
|
"f_polytubes",
|
|
"f_ridge",
|
|
"f_ridged_mf",
|
|
"f_spiral",
|
|
"f_witch_of_agnesi",
|
|
}:
|
|
func = 6
|
|
if tex.pov.func_list in {"f_helix1", "f_helix2", "f_piriform_2d", "f_strophoid_2d"}:
|
|
func = 7
|
|
if tex.pov.func_list == "f_helical_torus":
|
|
func = 8
|
|
column_flow = layout.column_flow(columns=3, align=True)
|
|
column_flow.label(text="X")
|
|
column_flow.prop(tex.pov, "func_plus_x", text="")
|
|
column_flow.prop(tex.pov, "func_x", text="Value")
|
|
column_flow = layout.column_flow(columns=3, align=True)
|
|
column_flow.label(text="Y")
|
|
column_flow.prop(tex.pov, "func_plus_y", text="")
|
|
column_flow.prop(tex.pov, "func_y", text="Value")
|
|
column_flow = layout.column_flow(columns=3, align=True)
|
|
column_flow.label(text="Z")
|
|
column_flow.prop(tex.pov, "func_plus_z", text="")
|
|
column_flow.prop(tex.pov, "func_z", text="Value")
|
|
row = layout.row(align=align)
|
|
if func > 0:
|
|
row.prop(tex.pov, "func_P0", text="P0")
|
|
if func > 1:
|
|
row.prop(tex.pov, "func_P1", text="P1")
|
|
row = layout.row(align=align)
|
|
if func > 2:
|
|
row.prop(tex.pov, "func_P2", text="P2")
|
|
if func > 3:
|
|
row.prop(tex.pov, "func_P3", text="P3")
|
|
row = layout.row(align=align)
|
|
if func > 4:
|
|
row.prop(tex.pov, "func_P4", text="P4")
|
|
if func > 5:
|
|
row.prop(tex.pov, "func_P5", text="P5")
|
|
row = layout.row(align=align)
|
|
if func > 6:
|
|
row.prop(tex.pov, "func_P6", text="P6")
|
|
if func > 7:
|
|
row.prop(tex.pov, "func_P7", text="P7")
|
|
row = layout.row(align=align)
|
|
row.prop(tex.pov, "func_P8", text="P8")
|
|
row.prop(tex.pov, "func_P9", text="P9")
|
|
# ------------------------- End Patterns ------------------------- #
|
|
|
|
layout.prop(tex.pov, "warp_types", text="Warp types") # warp
|
|
if tex.pov.warp_types == "TOROIDAL":
|
|
layout.prop(tex.pov, "warp_tor_major_radius", text="Major radius")
|
|
if tex.pov.warp_types not in {"CUBIC", "NONE"}:
|
|
layout.prop(tex.pov, "warp_orientation", text="Warp orientation")
|
|
col = layout.column(align=align)
|
|
row = col.row()
|
|
row.prop(tex.pov, "warp_dist_exp", text="Distance exponent")
|
|
row = col.row()
|
|
row.prop(tex.pov, "modifier_frequency", text="Frequency")
|
|
row.prop(tex.pov, "modifier_phase", text="Phase")
|
|
|
|
row = layout.row()
|
|
|
|
row.label(text="Offset:")
|
|
row.label(text="Scale:")
|
|
row.label(text="Rotate:")
|
|
col = layout.column(align=align)
|
|
row = col.row()
|
|
row.prop(tex.pov, "tex_mov_x", text="X")
|
|
row.prop(tex.pov, "tex_scale_x", text="X")
|
|
row.prop(tex.pov, "tex_rot_x", text="X")
|
|
row = col.row()
|
|
row.prop(tex.pov, "tex_mov_y", text="Y")
|
|
row.prop(tex.pov, "tex_scale_y", text="Y")
|
|
row.prop(tex.pov, "tex_rot_y", text="Y")
|
|
row = col.row()
|
|
row.prop(tex.pov, "tex_mov_z", text="Z")
|
|
row.prop(tex.pov, "tex_scale_z", text="Z")
|
|
row.prop(tex.pov, "tex_rot_z", text="Z")
|
|
row = layout.row()
|
|
|
|
row.label(text="Turbulence:")
|
|
col = layout.column(align=align)
|
|
row = col.row()
|
|
row.prop(tex.pov, "warp_turbulence_x", text="X")
|
|
row.prop(tex.pov, "modifier_octaves", text="Octaves")
|
|
row = col.row()
|
|
row.prop(tex.pov, "warp_turbulence_y", text="Y")
|
|
row.prop(tex.pov, "modifier_lambda", text="Lambda")
|
|
row = col.row()
|
|
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)
|
|
mat = bpy.context.active_object.active_material
|
|
# 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."""
|
|
|
|
bl_label = "Influence"
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
bl_space_type = "PROPERTIES"
|
|
bl_region_type = "WINDOW"
|
|
# bl_context = 'texture'
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
idblock = pov_context_tex_datablock(context)
|
|
if (
|
|
# 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
|
|
|
|
# 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
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
idblock = pov_context_tex_datablock(context)
|
|
# tex = context.pov_texture_slot
|
|
# mat = bpy.context.active_object.active_material
|
|
texslot = idblock.pov_texture_slots[
|
|
idblock.pov.active_texture_index
|
|
] # bpy.data.textures[mat.active_texture_index]
|
|
# below tex unused yet ...maybe for particles?
|
|
try:
|
|
tex = bpy.data.textures[
|
|
idblock.pov_texture_slots[idblock.pov.active_texture_index].texture
|
|
] # NOT USED
|
|
except KeyError:
|
|
tex = None # NOT USED
|
|
|
|
def factor_but(layout, toggle, factor, name):
|
|
row = layout.row(align=True)
|
|
row.prop(texslot, toggle, text="")
|
|
sub = row.row(align=True)
|
|
sub.active = getattr(texslot, toggle)
|
|
sub.prop(texslot, factor, text=name, slider=True)
|
|
return sub # XXX, temp. use_map_normal needs to override.
|
|
|
|
if isinstance(idblock, Material):
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
if idblock.pov.type in {"SURFACE", "WIRE"}:
|
|
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
col.label(text="Diffuse:")
|
|
factor_but(col, "use_map_diffuse", "diffuse_factor", "Intensity")
|
|
factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
|
|
factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
|
|
factor_but(col, "use_map_translucency", "translucency_factor", "Translucency")
|
|
|
|
col.label(text="Specular:")
|
|
factor_but(col, "use_map_specular", "specular_factor", "Intensity")
|
|
factor_but(col, "use_map_color_spec", "specular_color_factor", "Color")
|
|
factor_but(col, "use_map_hardness", "hardness_factor", "Hardness")
|
|
|
|
col = split.column()
|
|
col.label(text="Shading:")
|
|
factor_but(col, "use_map_ambient", "ambient_factor", "Ambient")
|
|
factor_but(col, "use_map_emit", "emit_factor", "Emit")
|
|
factor_but(col, "use_map_mirror", "mirror_factor", "Mirror")
|
|
factor_but(col, "use_map_raymir", "raymir_factor", "Ray Mirror")
|
|
|
|
col.label(text="Geometry:")
|
|
# XXX replace 'or' when displacement is fixed to not rely on normal influence value.
|
|
sub_tmp = factor_but(col, "use_map_normal", "normal_factor", "Normal")
|
|
sub_tmp.active = texslot.use_map_normal or texslot.use_map_displacement
|
|
# END XXX
|
|
|
|
factor_but(col, "use_map_warp", "warp_factor", "Warp")
|
|
factor_but(col, "use_map_displacement", "displacement_factor", "Displace")
|
|
|
|
elif idblock.pov.type == "HALO":
|
|
layout.label(text="Halo:")
|
|
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
|
|
factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_raymir", "raymir_factor", "Size")
|
|
factor_but(col, "use_map_hardness", "hardness_factor", "Hardness")
|
|
factor_but(col, "use_map_translucency", "translucency_factor", "Add")
|
|
elif idblock.pov.type == "VOLUME":
|
|
layout.label(text="Volume:")
|
|
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_density", "density_factor", "Density")
|
|
factor_but(col, "use_map_emission", "emission_factor", "Emission")
|
|
factor_but(col, "use_map_scatter", "scattering_factor", "Scattering")
|
|
factor_but(col, "use_map_reflect", "reflection_factor", "Reflection")
|
|
|
|
col = split.column()
|
|
col.label(text=" ")
|
|
factor_but(col, "use_map_color_emission", "emission_color_factor", "Emission Color")
|
|
factor_but(
|
|
col,
|
|
"use_map_color_transmission",
|
|
"transmission_color_factor",
|
|
"Transmission Color",
|
|
)
|
|
factor_but(
|
|
col, "use_map_color_reflection", "reflection_color_factor", "Reflection Color"
|
|
)
|
|
|
|
layout.label(text="Geometry:")
|
|
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_warp", "warp_factor", "Warp")
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_displacement", "displacement_factor", "Displace")
|
|
|
|
elif isinstance(idblock, Light):
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_color", "color_factor", "Color")
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_shadow", "shadow_factor", "Shadow")
|
|
|
|
elif isinstance(idblock, World):
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_blend", "blend_factor", "Blend")
|
|
factor_but(col, "use_map_horizon", "horizon_factor", "Horizon")
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up")
|
|
factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down")
|
|
elif isinstance(idblock, ParticleSettings):
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
col.label(text="General:")
|
|
factor_but(col, "use_map_time", "time_factor", "Time")
|
|
factor_but(col, "use_map_life", "life_factor", "Lifetime")
|
|
factor_but(col, "use_map_density", "density_factor", "Density")
|
|
factor_but(col, "use_map_size", "size_factor", "Size")
|
|
|
|
col = split.column()
|
|
col.label(text="Physics:")
|
|
factor_but(col, "use_map_velocity", "velocity_factor", "Velocity")
|
|
factor_but(col, "use_map_damp", "damp_factor", "Damp")
|
|
factor_but(col, "use_map_gravity", "gravity_factor", "Gravity")
|
|
factor_but(col, "use_map_field", "field_factor", "Force Fields")
|
|
|
|
layout.label(text="Hair:")
|
|
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_length", "length_factor", "Length")
|
|
factor_but(col, "use_map_clump", "clump_factor", "Clump")
|
|
factor_but(col, "use_map_twist", "twist_factor", "Twist")
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude")
|
|
factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency")
|
|
factor_but(col, "use_map_rough", "rough_factor", "Rough")
|
|
|
|
elif isinstance(idblock, FreestyleLineStyle):
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
|
|
col = split.column()
|
|
factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
|
|
|
|
layout.separator()
|
|
|
|
if not isinstance(idblock, ParticleSettings):
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
# col.prop(tex, "blend_type", text="Blend") #deprecated since 2.8
|
|
# col.prop(tex, "use_rgb_to_intensity") #deprecated since 2.8
|
|
# color is used on gray-scale textures even when use_rgb_to_intensity is disabled.
|
|
# col.prop(tex, "color", text="") #deprecated since 2.8
|
|
|
|
col = split.column()
|
|
# col.prop(tex, "invert", text="Negative") #deprecated since 2.8
|
|
# col.prop(tex, "use_stencil") #deprecated since 2.8
|
|
|
|
# if isinstance(idblock, (Material, World)):
|
|
# col.prop(tex, "default_value", text="DVar", slider=True)
|
|
|
|
|
|
class TEXTURE_PT_POV_tex_gamma(TextureButtonsPanel, Panel):
|
|
"""Use this class to define pov texture gamma buttons."""
|
|
|
|
bl_label = "Image Gamma"
|
|
COMPAT_ENGINES = {"POVRAY_RENDER"}
|
|
|
|
def draw_header(self, context):
|
|
tex = context.texture
|
|
|
|
self.layout.prop(tex.pov, "tex_gamma_enable", text="", icon="SEQ_LUMA_WAVEFORM")
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
tex = context.texture
|
|
|
|
layout.active = tex.pov.tex_gamma_enable
|
|
layout.prop(tex.pov, "tex_gamma_value", text="Gamma Value")
|
|
|
|
|
|
# commented out below UI for texture only custom code inside exported material:
|
|
# class TEXTURE_PT_povray_replacement_text(TextureButtonsPanel, Panel):
|
|
# bl_label = "Custom POV Code"
|
|
# COMPAT_ENGINES = {'POVRAY_RENDER'}
|
|
|
|
# def draw(self, context):
|
|
# layout = self.layout
|
|
|
|
# tex = context.texture
|
|
|
|
# col = layout.column()
|
|
# col.label(text="Replace properties with:")
|
|
# col.prop(tex.pov, "replacement_text", text="")
|
|
|
|
|
|
classes = (
|
|
WORLD_TEXTURE_SLOTS_UL_POV_layerlist,
|
|
TEXTURE_MT_POV_specials,
|
|
# TEXTURE_PT_context # todo: solve UI design for painting
|
|
TEXTURE_PT_POV_context_texture,
|
|
TEXTURE_PT_colors,
|
|
TEXTURE_PT_POV_type,
|
|
TEXTURE_PT_POV_preview,
|
|
TEXTURE_PT_POV_parameters,
|
|
TEXTURE_PT_POV_tex_gamma,
|
|
MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist,
|
|
TEXTURE_OT_POV_texture_slot_add,
|
|
TEXTURE_OT_POV_texture_slot_remove,
|
|
TEXTURE_OT_POV_context_texture_update,
|
|
TEXTURE_PT_POV_influence,
|
|
TEXTURE_PT_POV_mapping,
|
|
)
|
|
|
|
|
|
def register():
|
|
for cls in classes:
|
|
register_class(cls)
|
|
|
|
|
|
def unregister():
|
|
for cls in reversed(classes):
|
|
# if cls != TEXTURE_PT_context:
|
|
unregister_class(cls)
|