Merged changes in the trunk up to revision 53584.

Conflicts resolved:
release/scripts/startup/bl_ui/properties_render.py
source/blender/blenloader/intern/readfile.c
source/blender/editors/interface/interface_templates.c
source/blender/makesrna/RNA_enum_types.h

Also made additional code updates for:
r53355 UIList - Python-extendable list of UI items
r53460 Alpha premul pipeline cleanup
This commit is contained in:
Tamito Kajiyama
2013-01-05 22:24:05 +00:00
577 changed files with 20475 additions and 7280 deletions

View File

@@ -81,6 +81,8 @@ LANGUAGES = (
(35, "Esperanto (Esperanto)", "eo"),
(36, "Spanish from Spain (Español de España)", "es_ES"),
(37, "Amharic (አማርኛ)", "am_ET"),
(38, "Uzbek (Oʻzbek)", "uz_UZ"),
(39, "Uzbek Cyrillic (Ўзбек)", "uz_UZ@cyrillic"),
)
# Name of language file used by Blender to generate translations' menu.
@@ -91,7 +93,7 @@ LANGUAGES_FILE = "languages"
IMPORT_MIN_LEVEL = -1
# Languages in /branches we do not want to import in /trunk currently...
IMPORT_LANGUAGES_SKIP = {'bg', 'ca', 'fi', 'el', 'ko', 'ne', 'pl', 'ro'}
IMPORT_LANGUAGES_SKIP = {'am', 'bg', 'fi', 'el', 'et', 'ko', 'ne', 'pl', 'ro', 'uz', 'uz@cyrillic'}
# The comment prefix used in generated messages.txt file.
COMMENT_PREFIX = "#~ "

View File

@@ -188,6 +188,7 @@ dict_uimsgs = {
"occluder",
"passepartout",
"perspectively",
"pixelate",
"polygonization",
"selectability",
"slurph",
@@ -195,7 +196,7 @@ dict_uimsgs = {
"symmetrize",
"trackability",
"transmissivity",
"rasterized", "rasterization",
"rasterized", "rasterization", "rasterizer",
"renderer", "renderable", "renderability",
# Abbreviations
@@ -380,6 +381,7 @@ dict_uimsgs = {
"texface",
"timeline", "timelines",
"tosphere",
"uilist",
"vcol", "vcols",
"vgroup", "vgroups",
"vinterlace",

View File

@@ -30,6 +30,9 @@ __all__ = (
"display_name",
"display_name_from_filepath",
"ensure_ext",
"extensions_image",
"extensions_movie",
"extensions_audio",
"is_subdir",
"module_names",
"relpath",
@@ -39,6 +42,10 @@ __all__ = (
import bpy as _bpy
import os as _os
from _bpy_path import (extensions_audio,
extensions_movie,
extensions_image,
)
def abspath(path, start=None, library=None):
"""

View File

@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
# <pep8-80 compliant>
# <pep8 compliant>
__all__ = (
"bake_action",
@@ -52,7 +52,7 @@ def bake_action(frame_start,
:type do_pose: bool
:arg do_object: Bake objects.
:type do_object: bool
:arg do_constraint_clear: Remove constraints.
:arg do_constraint_clear: Remove constraints (and do 'visual keying').
:type do_constraint_clear: bool
:arg do_clean: Remove redundant keyframes after baking.
:type do_clean: bool
@@ -65,61 +65,20 @@ def bake_action(frame_start,
"""
# -------------------------------------------------------------------------
# Helper Functions
# Helper Functions and vars
def pose_frame_info(obj):
from mathutils import Matrix
def pose_frame_info(obj, do_visual_keying):
matrix = {}
for name, pbone in obj.pose.bones.items():
if do_visual_keying:
# Get the final transform of the bone in its own local space...
matrix[name] = obj.convert_space(pbone, pbone.matrix, 'POSE', 'LOCAL')
else:
matrix[name] = pbone.matrix_basis.copy()
return matrix
info = {}
pose = obj.pose
pose_items = pose.bones.items()
for name, pbone in pose_items:
binfo = {}
bone = pbone.bone
binfo["parent"] = getattr(bone.parent, "name", None)
binfo["bone"] = bone
binfo["pbone"] = pbone
binfo["matrix_local"] = bone.matrix_local.copy()
try:
binfo["matrix_local_inv"] = binfo["matrix_local"].inverted()
except:
binfo["matrix_local_inv"] = Matrix()
binfo["matrix"] = bone.matrix.copy()
binfo["matrix_pose"] = pbone.matrix.copy()
try:
binfo["matrix_pose_inv"] = binfo["matrix_pose"].inverted()
except:
binfo["matrix_pose_inv"] = Matrix()
info[name] = binfo
for name, pbone in pose_items:
binfo = info[name]
binfo_parent = binfo.get("parent", None)
if binfo_parent:
binfo_parent = info[binfo_parent]
matrix = binfo["matrix_pose"]
rest_matrix = binfo["matrix_local"]
if binfo_parent:
matrix = binfo_parent["matrix_pose_inv"] * matrix
rest_matrix = binfo_parent["matrix_local_inv"] * rest_matrix
binfo["matrix_key"] = rest_matrix.inverted() * matrix
return info
def obj_frame_info(obj):
info = {}
# parent = obj.parent
info["matrix_key"] = obj.matrix_local.copy()
return info
def obj_frame_info(obj, do_visual_keying):
return obj.matrix_local.copy() if do_visual_keying else obj.matrix_basis.copy()
# -------------------------------------------------------------------------
# Setup the Context
@@ -127,33 +86,30 @@ def bake_action(frame_start,
# TODO, pass data rather then grabbing from the context!
scene = bpy.context.scene
obj = bpy.context.object
pose = obj.pose
frame_back = scene.frame_current
if pose is None:
if obj.pose is None:
do_pose = False
if do_pose is None and do_object is None:
if not (do_pose or do_object):
return None
pose_info = []
obj_info = []
options = {'INSERTKEY_NEEDED'}
frame_range = range(frame_start, frame_end + 1, frame_step)
# -------------------------------------------------------------------------
# Collect transformations
# could speed this up by applying steps here too...
for f in frame_range:
scene.frame_set(f)
if do_pose:
pose_info.append(pose_frame_info(obj))
pose_info.append(pose_frame_info(obj, do_constraint_clear))
if do_object:
obj_info.append(obj_frame_info(obj))
f += 1
obj_info.append(obj_frame_info(obj, do_constraint_clear))
# -------------------------------------------------------------------------
# Create action
@@ -164,57 +120,44 @@ def bake_action(frame_start,
action = bpy.data.actions.new("Action")
atd.action = action
if do_pose:
pose_items = pose.bones.items()
else:
pose_items = [] # skip
# -------------------------------------------------------------------------
# Apply transformations to action
# pose
for name, pbone in (pose_items if do_pose else ()):
if only_selected and not pbone.bone.select:
continue
if do_pose:
for name, pbone in obj.pose.bones.items():
if only_selected and not pbone.bone.select:
continue
if do_constraint_clear:
while pbone.constraints:
pbone.constraints.remove(pbone.constraints[0])
if do_constraint_clear:
while pbone.constraints:
pbone.constraints.remove(pbone.constraints[0])
# create compatible eulers
euler_prev = None
# create compatible eulers
euler_prev = None
for f in frame_range:
f_step = (f - frame_start) // frame_step
matrix = pose_info[f_step][name]["matrix_key"]
for (f, matrix) in zip(frame_range, pose_info):
pbone.matrix_basis = matrix[name].copy()
# pbone.location = matrix.to_translation()
# pbone.rotation_quaternion = matrix.to_quaternion()
pbone.matrix_basis = matrix
pbone.keyframe_insert("location", -1, f, name, options)
pbone.keyframe_insert("location", -1, f, name)
rotation_mode = pbone.rotation_mode
if rotation_mode == 'QUATERNION':
pbone.keyframe_insert("rotation_quaternion", -1, f, name, options)
elif rotation_mode == 'AXIS_ANGLE':
pbone.keyframe_insert("rotation_axis_angle", -1, f, name, options)
else: # euler, XYZ, ZXY etc
if euler_prev is not None:
euler = pbone.rotation_euler.copy()
euler.make_compatible(euler_prev)
pbone.rotation_euler = euler
euler_prev = euler
del euler
else:
euler_prev = pbone.rotation_euler.copy()
pbone.keyframe_insert("rotation_euler", -1, f, name, options)
rotation_mode = pbone.rotation_mode
if rotation_mode == 'QUATERNION':
pbone.keyframe_insert("rotation_quaternion", -1, f, name)
elif rotation_mode == 'AXIS_ANGLE':
pbone.keyframe_insert("rotation_axis_angle", -1, f, name)
else: # euler, XYZ, ZXY etc
if euler_prev is not None:
euler = pbone.rotation_euler.copy()
euler.make_compatible(euler_prev)
pbone.rotation_euler = euler
euler_prev = euler
del euler
pbone.keyframe_insert("rotation_euler", -1, f, name)
if euler_prev is None:
euler_prev = pbone.rotation_euler.copy()
pbone.keyframe_insert("scale", -1, f, name)
pbone.keyframe_insert("scale", -1, f, name, options)
# object. TODO. multiple objects
if do_object:
@@ -225,18 +168,16 @@ def bake_action(frame_start,
# create compatible eulers
euler_prev = None
for f in frame_range:
matrix = obj_info[(f - frame_start) // frame_step]["matrix_key"]
obj.matrix_local = matrix
for (f, matrix) in zip(frame_range, obj_info):
obj.matrix_basis = matrix[name]
obj.keyframe_insert("location", -1, f)
obj.keyframe_insert("location", -1, f, options)
rotation_mode = obj.rotation_mode
if rotation_mode == 'QUATERNION':
obj.keyframe_insert("rotation_quaternion", -1, f)
obj.keyframe_insert("rotation_quaternion", -1, f, options)
elif rotation_mode == 'AXIS_ANGLE':
obj.keyframe_insert("rotation_axis_angle", -1, f)
obj.keyframe_insert("rotation_axis_angle", -1, f, options)
else: # euler, XYZ, ZXY etc
if euler_prev is not None:
euler = obj.rotation_euler.copy()
@@ -244,15 +185,11 @@ def bake_action(frame_start,
obj.rotation_euler = euler
euler_prev = euler
del euler
obj.keyframe_insert("rotation_euler", -1, f)
if euler_prev is None:
else:
euler_prev = obj.rotation_euler.copy()
obj.keyframe_insert("rotation_euler", -1, f, options)
obj.keyframe_insert("scale", -1, f)
scene.frame_set(frame_back)
obj.keyframe_insert("scale", -1, f, options)
# -------------------------------------------------------------------------
# Clean
@@ -271,4 +208,6 @@ def bake_action(frame_start,
else:
i += 1
scene.frame_set(frame_back)
return action

View File

@@ -26,7 +26,6 @@ __all__ = (
import bpy
import mathutils
from bpy.props import BoolProperty, FloatVectorProperty
@@ -80,7 +79,7 @@ def add_object_align_init(context, operator):
rotation = space_data.region_3d.view_matrix.to_3x3().inverted()
rotation.resize_4x4()
else:
rotation = mathutils.Matrix()
rotation = Matrix()
# set the operator properties
if operator:

View File

@@ -673,6 +673,10 @@ class Panel(StructRNA, _GenericUI, metaclass=RNAMeta):
__slots__ = ()
class UIList(StructRNA, _GenericUI, metaclass=RNAMeta):
__slots__ = ()
class Header(StructRNA, _GenericUI, metaclass=RNAMeta):
__slots__ = ()

View File

@@ -47,7 +47,7 @@ _modules = [
import bpy
if 'FREESTYLE' in bpy.app.build_options:
if bpy.app.build_options.freestyle:
_modules.append("freestyle")
__import__(name=__name__, fromlist=_modules)
_namespace = globals()

View File

@@ -19,7 +19,6 @@
# <pep8-80 compliant>
import bpy
from bpy.types import Operator
import mathutils
from bpy.props import (FloatProperty,
IntProperty,
@@ -31,9 +30,7 @@ from bpy_extras import object_utils
def add_torus(major_rad, minor_rad, major_seg, minor_seg):
from math import cos, sin, pi
Vector = mathutils.Vector
Quaternion = mathutils.Quaternion
from mathutils import Vector, Quaternion
PI_2 = pi * 2.0
z_axis = 0.0, 0.0, 1.0

View File

@@ -187,17 +187,20 @@ class BakeAction(Operator):
)
only_selected = BoolProperty(
name="Only Selected",
description="Only key selected object/bones",
default=True,
)
clear_constraints = BoolProperty(
name="Clear Constraints",
description="Remove all constraints from keyed object/bones, and do 'visual' keying",
default=False,
)
bake_types = EnumProperty(
name="Bake Data",
description="Which data's transformations to bake",
options={'ENUM_FLAG'},
items=(('POSE', "Pose", ""),
('OBJECT', "Object", ""),
items=(('POSE', "Pose", "Bake bones transformations"),
('OBJECT', "Object", "Bake object transformations"),
),
default={'POSE'},
)
@@ -208,12 +211,12 @@ class BakeAction(Operator):
action = anim_utils.bake_action(self.frame_start,
self.frame_end,
self.step,
self.only_selected,
'POSE' in self.bake_types,
'OBJECT' in self.bake_types,
self.clear_constraints,
True,
frame_step=self.step,
only_selected=self.only_selected,
do_pose='POSE' in self.bake_types,
do_object='OBJECT' in self.bake_types,
do_constraint_clear=self.clear_constraints,
do_clean=True,
)
if action is None:

View File

@@ -20,7 +20,7 @@
import bpy
from bpy.types import Operator
from bpy.props import EnumProperty, StringProperty
from bpy.props import BoolProperty, EnumProperty, StringProperty
# Base class for node 'Add' operators
class NodeAddOperator():
@@ -75,6 +75,11 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
name="Group tree",
description="Group node tree name",
)
use_transform = BoolProperty(
name="Use Transform",
description="Start transform operator after inserting the node",
default = False,
)
def execute(self, context):
node = self.create_node(context, self.type)
@@ -84,27 +89,13 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
return {'FINISHED'}
# Adds a node and immediately starts the transform operator for inserting in a tree
class NODE_OT_add_node_move(NODE_OT_add_node):
'''Add a node to the active tree and start transform'''
bl_idname = "node.add_node_move"
bl_label = "Add Node and Move"
type = StringProperty(
name="Node Type",
description="Node type",
)
# optional group tree parameter for group nodes
group_tree = StringProperty(
name="Group tree",
description="Group node tree name",
)
def invoke(self, context, event):
self.store_mouse_cursor(context, event)
self.execute(context)
return bpy.ops.transform.translate('INVOKE_DEFAULT')
result = self.execute(context)
if self.use_transform and ('FINISHED' in result):
return bpy.ops.transform.translate('INVOKE_DEFAULT')
else:
return result
# XXX These node item lists should actually be generated by a callback at

View File

@@ -26,6 +26,7 @@ from bpy.types import Operator
def extend(obj, operator, EXTEND_MODE):
import bmesh
me = obj.data
# script will fail without UVs
@@ -46,12 +47,12 @@ def extend(obj, operator, EXTEND_MODE):
faces = [f for f in bm.faces if f.select and len(f.verts) == 4]
for f in faces:
f.tag = False
f_act.tag = True
# our own local walker
def walk_face_init(faces, f_act):
for f in faces:
f.tag = False
f_act.tag = True
def walk_face(f):
# all faces in this list must be tagged
f.tag = True
@@ -73,6 +74,30 @@ def extend(obj, operator, EXTEND_MODE):
faces_a, faces_b = faces_b, faces_a
faces_b.clear()
def walk_edgeloop(l):
"""
Could make this a generic function
"""
e_first = l.edge
e = None
while True:
e = l.edge
yield e
# don't step past non-manifold edges
if e.is_manifold:
# welk around the quad and then onto the next face
l = l.link_loop_radial_next
if len(l.face.verts) == 4:
l = l.link_loop_next.link_loop_next
if l.edge is e_first:
break
else:
break
else:
break
def extrapolate_uv(fac,
l_a_outer, l_a_inner,
l_b_outer, l_b_inner):
@@ -119,7 +144,9 @@ def extend(obj, operator, EXTEND_MODE):
l_a_uv = [l[uv_act].uv for l in l_a]
l_b_uv = [l[uv_act].uv for l in l_b]
if EXTEND_MODE == 'LENGTH':
if EXTEND_MODE == 'LENGTH_AVERAGE':
fac = edge_lengths[l_b[2].edge.index][0] / edge_lengths[l_a[1].edge.index][0]
elif EXTEND_MODE == 'LENGTH':
a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co
a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co
@@ -140,6 +167,40 @@ def extend(obj, operator, EXTEND_MODE):
l_a_uv[2], l_a_uv[1],
l_b_uv[2], l_b_uv[1])
# -------------------------------------------
# Calculate average length per loop if needed
if EXTEND_MODE == 'LENGTH_AVERAGE':
bm.edges.index_update()
edge_lengths = [None] * len(bm.edges)
for f in faces:
# we know its a quad
l_quad = f.loops[:]
l_pair_a = (l_quad[0], l_quad[2])
l_pair_b = (l_quad[1], l_quad[3])
for l_pair in (l_pair_a, l_pair_b):
if edge_lengths[l_pair[0].edge.index] is None:
edge_length_store = [-1.0]
edge_length_accum = 0.0
edge_length_total = 0
for l in l_pair:
if edge_lengths[l.edge.index] is None:
for e in walk_edgeloop(l):
if edge_lengths[e.index] is None:
edge_lengths[e.index] = edge_length_store
edge_length_accum += e.calc_length()
edge_length_total += 1
edge_length_store[0] = edge_length_accum / edge_length_total
# done with average length
# ------------------------
walk_face_init(faces, f_act)
for f_triple in walk_face(f_act):
apply_uv(*f_triple)
@@ -162,8 +223,10 @@ class FollowActiveQuads(Operator):
name="Edge Length Mode",
description="Method to space UV edge loops",
items=(('EVEN', "Even", "Space all UVs evenly"),
('LENGTH', "Length", "Average space UVs edge length of each loop")),
default='LENGTH',
('LENGTH', "Length", "Average space UVs edge length of each loop"),
('LENGTH_AVERAGE', "Length Average", "Average space UVs edge length of each loop"),
),
default='LENGTH_AVERAGE',
)
@classmethod

View File

@@ -127,13 +127,14 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
col[0] = tone * col[0]
col[1] = tone * col[1]
col[2] = tone * col[2]
me.update()
return {'FINISHED'}
import bpy
from bpy.types import Operator
from bpy.props import FloatProperty, IntProperty, BoolProperty
from math import pi
class VertexPaintDirt(Operator):
@@ -156,14 +157,16 @@ class VertexPaintDirt(Operator):
clean_angle = FloatProperty(
name="Highlight Angle",
description="Less than 90 limits the angle used in the tonal range",
min=0.0, max=180.0,
default=180.0,
min=0.0, max=pi,
default=pi,
unit="ROTATION",
)
dirt_angle = FloatProperty(
name="Dirt Angle",
description="Less than 90 limits the angle used in the tonal range",
min=0.0, max=180.0,
min=0.0, max=pi,
default=0.0,
unit="ROTATION",
)
dirt_only = BoolProperty(
name="Dirt Only",
@@ -171,20 +174,21 @@ class VertexPaintDirt(Operator):
default=False,
)
@classmethod
def poll(cls, context):
obj = context.object
return (obj and obj.type == 'MESH')
def execute(self, context):
import time
from math import radians
obj = context.object
if not obj or obj.type != 'MESH':
self.report({'ERROR'}, "Error, no active mesh object, aborting")
return {'CANCELLED'}
mesh = obj.data
t = time.time()
ret = applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, radians(self.dirt_angle), radians(self.clean_angle), self.dirt_only)
ret = applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, self.dirt_angle, self.clean_angle, self.dirt_only)
print('Dirt calculated in %.6f' % (time.time() - t))

View File

@@ -133,3 +133,9 @@ def register():
def unregister():
bpy.utils.unregister_module(__name__)
# Define a default UIList, when a list does not need any custom drawing...
class UI_UL_list(bpy.types.UIList):
pass
bpy.utils.register_class(UI_UL_list)

View File

@@ -124,7 +124,7 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
rows = 2
if group:
rows = 5
row.template_list(pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
row.template_list("UI_UL_list", "", pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
col = row.column(align=True)
col.active = (ob.proxy is None)
@@ -184,7 +184,7 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
if poselib:
# list of poses in pose library
row = layout.row()
row.template_list(poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
row.template_list("UI_UL_list", "", poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
# column of operators for active pose
# - goes beside list

View File

@@ -80,7 +80,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
row = col.row()
if cam.lens_unit == 'MILLIMETERS':
row.prop(cam, "lens")
elif cam.lens_unit == 'DEGREES':
elif cam.lens_unit == 'FOV':
row.prop(cam, "angle")
row.prop(cam, "lens_unit", text="")

View File

@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Menu, Panel
from bpy.types import Menu, Panel, UIList
from rna_prop_ui import PropertyPanel
@@ -54,6 +54,53 @@ class MESH_MT_shape_key_specials(Menu):
layout.operator("object.shape_key_add", icon='ZOOMIN', text="New Shape From Mix").from_mix = True
class MESH_UL_vgroups(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.VertexGroup)
vgroup = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(vgroup.name, icon_value=icon)
icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
class MESH_UL_shape_keys(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.ShapeKey)
obj = active_data
key = data
key_block = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
split = layout.split(0.66, False)
split.label(item.name, icon_value=icon)
row = split.row(True)
if key_block.mute or (obj.mode == 'EDIT' and not (obj.use_shape_key_edit_mode and obj.type == 'MESH')):
row.active = False
if not item.relative_key or index > 0:
row.prop(key_block, "value", text="", emboss=False)
else:
row.label("")
row.prop(key_block, "mute", text="", emboss=False)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
class MESH_UL_uvmaps_vcols(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, (bpy.types.MeshTexturePolyLayer, bpy.types.MeshLoopColorLayer))
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(item.name, icon_value=icon)
icon = 'RESTRICT_RENDER_OFF' if item.active_render else 'RESTRICT_RENDER_ON'
layout.prop(item, "active_render", text="", icon=icon, emboss=False)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
class MeshButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -144,7 +191,8 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
rows = 5
row = layout.row()
row.template_list(ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
row.template_list("MESH_UL_vgroups", "", ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
col = row.column(align=True)
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
@@ -202,7 +250,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
rows = 2
if kb:
rows = 5
row.template_list(key, "key_blocks", ob, "active_shape_key_index", rows=rows)
row.template_list("MESH_UL_shape_keys", "", key, "key_blocks", ob, "active_shape_key_index", rows=rows)
col = row.column()
@@ -282,7 +330,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
col.template_list(me, "uv_textures", me.uv_textures, "active_index", rows=2)
col.template_list("MESH_UL_uvmaps_vcols", "", me, "uv_textures", me.uv_textures, "active_index", rows=2)
col = row.column(align=True)
col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
@@ -305,7 +353,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
row = layout.row()
col = row.column()
col.template_list(me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
col.template_list("MESH_UL_uvmaps_vcols", "", me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
col = row.column(align=True)
col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="")

View File

@@ -489,11 +489,13 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.prop(md, "time")
col.prop(md, "resolution")
col.prop(md, "depth")
col.prop(md, "random_seed")
col = split.column()
col.prop(md, "resolution")
col.prop(md, "size")
col.prop(md, "spatial_size")
col.prop(md, "depth")
layout.label("Waves:")
@@ -534,7 +536,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
if md.is_cached:
layout.operator("object.ocean_bake", text="Free Bake").free = True
else:
layout.operator("object.ocean_bake")
layout.operator("object.ocean_bake").free = False
split = layout.split()
split.enabled = not md.is_cached
@@ -547,7 +549,15 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.label(text="Cache path:")
col.prop(md, "filepath", text="")
#col.prop(md, "bake_foam_fade")
split = layout.split()
split.enabled = not md.is_cached
col = split.column()
col.active = md.use_foam
col.prop(md, "bake_foam_fade")
col = split.column()
def PARTICLE_INSTANCE(self, layout, ob, md):
layout.prop(md, "object")

View File

@@ -407,6 +407,7 @@ class RENDER_PT_game_system(RenderButtonsPanel, Panel):
col = row.column()
col.prop(gs, "use_frame_rate")
col.prop(gs, "restrict_animation_updates")
col.prop(gs, "use_material_caching")
col = row.column()
col.prop(gs, "use_display_lists")
col.active = gs.raster_storage != 'VERTEX_BUFFER_OBJECT'

View File

@@ -22,7 +22,24 @@
# menus are referenced `as is`
import bpy
from bpy.types import Menu
from bpy.types import Menu, UIList
class MASK_UL_layers(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.MaskLayer)
mask = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
split = layout.split()
split.label(mask.name, icon_value=icon)
row = split.row(align=True)
row.prop(mask, "alpha", text="", emboss=False)
row.prop(mask, "hide", text="", emboss=False)
row.prop(mask, "hide_select", text="", emboss=False)
row.prop(mask, "hide_render", text="", emboss=False)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
class MASK_PT_mask:
@@ -69,8 +86,7 @@ class MASK_PT_layers:
rows = 5 if active_layer else 2
row = layout.row()
row.template_list(mask, "layers",
mask, "active_layer_index", rows=rows)
row.template_list("MASK_UL_layers", "", mask, "layers", mask, "active_layer_index", rows=rows)
sub = row.column(align=True)

View File

@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Menu, Panel
from bpy.types import Menu, Panel, UIList
from rna_prop_ui import PropertyPanel
@@ -69,6 +69,25 @@ class MATERIAL_MT_specials(Menu):
layout.operator("material.paste", icon='PASTEDOWN')
class MATERIAL_UL_matslots(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.MaterialSlot)
ob = data
slot = item
ma = slot.material
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(ma.name if ma else "", icon_value=icon)
if ma and not context.scene.render.use_shading_nodes:
manode = ma.active_node_material
if manode:
layout.label("Node %s" % manode.name, icon_value=layout.icon(manode))
elif ma.use_nodes:
layout.label("Node <none>")
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
class MaterialButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -104,7 +123,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
if ob:
row = layout.row()
row.template_list(ob, "material_slots", ob, "active_material_index", rows=2)
row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=2)
col = row.column(align=True)
col.operator("object.material_slot_add", icon='ZOOMIN', text="")

View File

@@ -96,7 +96,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
if ob:
row = layout.row()
row.template_list(ob, "particle_systems", ob.particle_systems, "active_index", rows=2)
row.template_list("UI_UL_list", "", ob, "particle_systems", ob.particle_systems, "active_index", rows=2)
col = row.column(align=True)
col.operator("object.particle_system_add", icon='ZOOMIN', text="")
@@ -636,7 +636,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
layout.label(text="Fluid interaction:")
row = layout.row()
row.template_list(psys, "targets", psys, "active_particle_target_index")
row.template_list("UI_UL_list", "", psys, "targets", psys, "active_particle_target_index")
col = row.column()
sub = col.row()
@@ -702,7 +702,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
# Currently boids can only use the first state so these are commented out for now.
#row = layout.row()
#row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
#row.template_list("UI_UL_list", "", boids, "states", boids, "active_boid_state_index", compact="True")
#col = row.row()
#sub = col.row(align=True)
#sub.operator("boid.state_add", icon='ZOOMIN', text="")
@@ -723,7 +723,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
row.label(text="")
row = layout.row()
row.template_list(state, "rules", state, "active_boid_rule_index")
row.template_list("UI_UL_list", "", state, "rules", state, "active_boid_rule_index")
col = row.column()
sub = col.row()
@@ -886,7 +886,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
if part.use_group_count and not part.use_whole_group:
row = layout.row()
row.template_list(part, "dupli_weights", part, "active_dupliweight_index")
row.template_list("UI_UL_list", "", part, "dupli_weights", part, "active_dupliweight_index")
col = row.column()
sub = col.row()

View File

@@ -85,7 +85,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype):
layout.context_pointer_set("point_cache", cache)
row = layout.row()
row.template_list(cache, "point_caches", cache.point_caches, "active_index", rows=2)
row.template_list("UI_UL_list", "", cache, "point_caches", cache.point_caches, "active_index", rows=2)
col = row.column(align=True)
col.operator("ptcache.add", icon='ZOOMIN', text="")
col.operator("ptcache.remove", icon='ZOOMOUT', text="")

View File

@@ -18,13 +18,34 @@
# <pep8 compliant>
import bpy
from bpy.types import Panel
from bpy.types import Panel, UIList
from bl_ui.properties_physics_common import (point_cache_ui,
effector_weights_ui,
)
class PHYSICS_UL_dynapaint_surfaces(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.DynamicPaintSurface)
surf = item
sticon = layout.enum_item_icon(surf, "surface_type", surf.surface_type)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
row.label(text="", icon_value=icon)
row.label(text=surf.name, icon_value=sticon)
row = layout.row(align=True)
if surf.use_color_preview:
row.prop(surf, "show_preview", text="", emboss=False,
icon='RESTRICT_VIEW_OFF' if surf.show_preview else 'RESTRICT_VIEW_ON')
row.prop(surf, "is_active", text="")
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
row = layout.row(align=True)
row.label(text="", icon_value=icon)
row.label(text="", icon_value=sticon)
class PhysicButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -58,7 +79,8 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
surface = canvas.canvas_surfaces.active
row = layout.row()
row.template_list(canvas, "canvas_surfaces", canvas.canvas_surfaces, "active_index", rows=2)
row.template_list("PHYSICS_UL_dynapaint_surfaces", "", canvas, "canvas_surfaces",
canvas.canvas_surfaces, "active_index", rows=2)
col = row.column(align=True)
col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")

View File

@@ -62,8 +62,7 @@ class RenderFreestyleButtonsPanel(RenderButtonsPanel):
def poll(cls, context):
if not super().poll(context):
return False
rd = context.scene.render
return 'FREESTYLE' in bpy.app.build_options
return bpy.app.build_options.freestyle
class RENDER_PT_render(RenderButtonsPanel, Panel):
@@ -522,9 +521,12 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
split = layout.split()
col = split.column()
col.prop(rd, "use_bake_clear")
col.prop(rd, "bake_margin")
col.prop(rd, "bake_quad_split", text="Split")
col.prop(rd, "use_bake_to_vertex_color")
sub = col.column()
sub.active = not rd.use_bake_to_vertex_color
sub.prop(rd, "use_bake_clear")
sub.prop(rd, "bake_margin")
sub.prop(rd, "bake_quad_split", text="Split")
col = split.column()
col.prop(rd, "use_bake_selected_to_active")

View File

@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Menu, Panel
from bpy.types import Menu, Panel, UIList
class RenderLayerButtonsPanel():
@@ -41,7 +41,7 @@ class RenderLayerFreestyleButtonsPanel(RenderLayerButtonsPanel):
if not super().poll(context):
return False
rd = context.scene.render
return 'FREESTYLE' in bpy.app.build_options and rd.use_freestyle and rd.layers.active
return bpy.app.build_options.freestyle and rd.use_freestyle and rd.layers.active
class RenderLayerFreestyleEditorButtonsPanel(RenderLayerFreestyleButtonsPanel):
@@ -55,6 +55,46 @@ class RenderLayerFreestyleEditorButtonsPanel(RenderLayerFreestyleButtonsPanel):
return rl and rl.freestyle_settings.mode == 'EDITOR'
class RENDERLAYER_UL_renderlayers(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.SceneRenderLayer)
layer = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(layer.name, icon_value=icon)
layout.prop(layer, "use", text="", index=index)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
# else if (RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer)) {
# uiItemL(sub, name, icon);
# uiBlockSetEmboss(block, UI_EMBOSS);
# uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "use", 0, 0, 0, 0, 0, NULL);
# }
class RENDERLAYER_UL_linesets(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
lineset = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(lineset.name, icon_value=icon)
layout.prop(lineset, "use", text="", index=index)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
##ifdef WITH_FREESTYLE
# else if (RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer) ||
# RNA_struct_is_a(itemptr->type, &RNA_FreestyleLineSet)) {
##else
# else if (RNA_struct_is_a(itemptr->type, &RNA_SceneRenderLayer)) {
##endif
# uiItemL(sub, name, icon);
# uiBlockSetEmboss(block, UI_EMBOSS);
# uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "use", 0, 0, 0, 0, 0, NULL);
# }
class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
bl_label = "Layers"
bl_options = {'HIDE_HEADER'}
@@ -67,7 +107,7 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
rd = scene.render
row = layout.row()
row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
row.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
col = row.column(align=True)
col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
@@ -96,7 +136,7 @@ class RENDERLAYER_PT_layer_options(RenderLayerButtonsPanel, Panel):
col = split.column()
col.prop(scene, "layers", text="Scene")
# col.label(text="")
col.label(text="")
col.prop(rl, "light_override", text="Light")
col.prop(rl, "material_override", text="Material")
@@ -111,23 +151,22 @@ class RENDERLAYER_PT_layer_options(RenderLayerButtonsPanel, Panel):
split = layout.split()
col = split.column()
row = col.row(align=True)
row.prop(rl, "use_zmask")
sub = row.row(align=True)
sub.prop(rl, "invert_zmask", text="", icon='ZOOMOUT')
sub.active = rl.use_zmask
col.prop(rl, "use_zmask")
row = col.row()
row.prop(rl, "invert_zmask", text="Negate")
row.active = rl.use_zmask
col.prop(rl, "use_all_z")
col.prop(rl, "use_ztransp")
col = split.column()
col.prop(rl, "use_solid")
col.prop(rl, "use_halo")
col.prop(rl, "use_strand")
col.prop(rl, "use_ztransp")
col = split.column()
col.prop(rl, "use_sky")
col.prop(rl, "use_edge_enhance")
if 'FREESTYLE' in bpy.app.build_options:
col.prop(rl, "use_strand")
if bpy.app.build_options.freestyle:
row = col.row()
row.prop(rl, "use_freestyle")
row.active = rd.use_freestyle
@@ -267,7 +306,7 @@ class RENDERLAYER_PT_freestyle_lineset(RenderLayerFreestyleEditorButtonsPanel, P
col = layout.column()
row = col.row()
rows = 5 if lineset else 2
row.template_list(freestyle, "linesets", freestyle.linesets, "active_index", rows=rows)
row.template_list("RENDERLAYER_UL_linesets", "", freestyle, "linesets", freestyle.linesets, "active_index", rows=rows)
sub = row.column()
subsub = sub.column(align=True)

View File

@@ -18,10 +18,22 @@
# <pep8 compliant>
import bpy
from bpy.types import Panel
from bpy.types import Panel, UIList
from rna_prop_ui import PropertyPanel
class SCENE_UL_keying_set_paths(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.KeyingSetPath)
kspath = item
icon = layout.enum_item_icon(kspath, "id_type", kspath.id_type)
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(kspath.data_path, icon_value=icon)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
class SceneButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@@ -107,7 +119,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, Panel):
row = layout.row()
col = row.column()
col.template_list(scene, "keying_sets", scene.keying_sets, "active_index", rows=2)
col.template_list("UI_UL_list", "", scene, "keying_sets", scene.keying_sets, "active_index", rows=2)
col = row.column(align=True)
col.operator("anim.keying_set_add", icon='ZOOMIN', text="")
@@ -151,7 +163,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel):
row = layout.row()
col = row.column()
col.template_list(ks, "paths", ks.paths, "active_index", rows=2)
col.template_list("SCENE_UL_keying_set_paths", "", ks, "paths", ks.paths, "active_index", rows=2)
col = row.column(align=True)
col.operator("anim.keying_set_path_add", icon='ZOOMIN', text="")
@@ -251,7 +263,6 @@ class SCENE_PT_color_management(Panel):
col.separator()
col.label(text="Render:")
col.template_colormanaged_view_settings(scene, "view_settings")
col.prop(rd, "use_color_unpremultiply")
col = layout.column()
col.separator()

View File

@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Menu, Panel
from bpy.types import Menu, Panel, UIList
from bpy.types import (Brush,
Lamp,
@@ -55,6 +55,22 @@ class TEXTURE_MT_envmap_specials(Menu):
layout.operator("texture.envmap_clear", icon='FILE_REFRESH')
layout.operator("texture.envmap_clear_all", icon='FILE_REFRESH')
class TEXTURE_UL_texslots(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.MaterialTextureSlot)
ma = data
slot = item
tex = slot.texture if slot else None
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(tex.name if tex else "", icon_value=icon)
if tex:
layout.prop(ma, "use_textures", text="", index=index)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
from bl_ui.properties_material import active_node_mat
@@ -142,7 +158,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
if tex_collection:
row = layout.row()
row.template_list(idblock, "texture_slots", idblock, "active_texture_index", rows=2)
row.template_list("TEXTURE_UL_texslots", "", idblock, "texture_slots", idblock, "active_texture_index", rows=2)
col = row.column(align=True)
col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
@@ -426,7 +442,6 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
col = split.column()
col.label(text="Alpha:")
col.prop(tex, "use_alpha", text="Use")
col.prop(tex, "use_calculate_alpha", text="Calculate")
col.prop(tex, "invert_alpha", text="Invert")
col.separator()

View File

@@ -19,7 +19,18 @@
# <pep8-80 compliant>
import bpy
from bpy.types import Panel, Header, Menu
from bpy.types import Panel, Header, Menu, UIList
class CLIP_UL_tracking_objects(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.MovieTrackingObject)
tobj = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(tobj.name, icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA')
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA')
class CLIP_HT_header(Header):
@@ -471,8 +482,7 @@ class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
tracking = sc.clip.tracking
row = layout.row()
row.template_list(tracking, "objects",
tracking, "active_object_index", rows=3)
row.template_list("CLIP_UL_tracking_objects", "", tracking, "objects", tracking, "active_object_index", rows=3)
sub = row.column(align=True)
@@ -728,7 +738,7 @@ class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
layout.active = stab.use_2d_stabilization
row = layout.row()
row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
row.template_list("UI_UL_list", "", stab, "tracks", stab, "active_track_index", rows=3)
sub = row.column(align=True)

View File

@@ -433,7 +433,7 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel, Panel):
elem = False
if strip.type == 'IMAGE':
elem = strip.getStripElem(frame_current)
elem = strip.strip_elem_from_frame(frame_current)
elif strip.type == 'MOVIE':
elem = strip.elements[0]
@@ -595,13 +595,14 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
# Current element for the filename
elem = strip.getStripElem(context.scene.frame_current)
elem = strip.strip_elem_from_frame(context.scene.frame_current)
if elem:
split = layout.split(percentage=0.2)
split.label(text="File:")
split.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
layout.prop(strip.colorspace_settings, "name")
layout.prop(strip, "alpha_mode")
layout.operator("sequencer.change_path")
@@ -797,7 +798,6 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
col.label(text="Colors:")
col.prop(strip, "color_saturation", text="Saturation")
col.prop(strip, "color_multiply", text="Multiply")
col.prop(strip, "use_premultiply")
col.prop(strip, "use_float")

View File

@@ -194,14 +194,33 @@ class TEXT_MT_text(Menu):
layout.operator("text.run_script")
class TEXT_MT_templates_py(Menu):
bl_label = "Python"
def draw(self, context):
self.path_menu(bpy.utils.script_paths("templates_py"),
"text.open",
{"internal": True},
)
class TEXT_MT_templates_osl(Menu):
bl_label = "Open Shading Language"
def draw(self, context):
self.path_menu(bpy.utils.script_paths("templates_osl"),
"text.open",
{"internal": True},
)
class TEXT_MT_templates(Menu):
bl_label = "Templates"
def draw(self, context):
self.path_menu(bpy.utils.script_paths("templates"),
"text.open",
{"internal": True},
)
layout = self.layout
layout.menu("TEXT_MT_templates_py")
layout.menu("TEXT_MT_templates_osl")
class TEXT_MT_edit_select(Menu):
@@ -282,6 +301,7 @@ class TEXT_MT_edit(Menu):
layout.operator("text.jump")
layout.operator("text.properties", text="Find...")
layout.operator("text.autocomplete")
layout.separator()

View File

@@ -22,6 +22,27 @@ from bpy.types import Header, Menu, Panel
import os
def ui_style_items(col, context):
""" UI Style settings """
split = col.split()
col = split.column()
col.label(text="Kerning Style:")
col.row().prop(context, "font_kerning_style", expand=True)
col.prop(context, "points")
col = split.column()
col.label(text="Shadow Offset:")
col.prop(context, "shadow_offset_x", text="X")
col.prop(context, "shadow_offset_y", text="Y")
col = split.column()
col.prop(context, "shadow")
col.prop(context, "shadowalpha")
col.prop(context, "shadowcolor")
def ui_items_general(col, context):
""" General UI Theme Settings (User Interface)
"""
@@ -492,7 +513,7 @@ class USERPREF_PT_system(Panel):
sub.active = system.use_weight_color_range
sub.template_color_ramp(system, "weight_color_range", expand=True)
if 'INTERNATIONAL' in bpy.app.build_options:
if bpy.app.build_options.international:
column.separator()
column.prop(system, "use_international_fonts")
if system.use_international_fonts:
@@ -774,6 +795,21 @@ class USERPREF_PT_theme(Panel):
colsub = padding.column()
colsub = padding.column()
colsub.row().prop(ui, "show_colored_constraints")
elif theme.theme_area == 'STYLE':
col = split.column()
style = context.user_preferences.ui_styles[0]
ui = style.widget
col.label(text="Widget:")
ui_style_items(col, ui)
col.separator()
col.separator()
ui = style.widget_label
col.label(text="Widget Label:")
ui_style_items(col, ui)
else:
self._theme_generic(split, getattr(theme, theme.theme_area.lower()))
@@ -1126,7 +1162,8 @@ class USERPREF_PT_addons(Panel):
continue
# Addon UI Code
box = col.column().box()
col_box = col.column()
box = col_box.box()
colsub = box.column()
row = colsub.row()
@@ -1189,6 +1226,25 @@ class USERPREF_PT_addons(Panel):
for i in range(4 - tot_row):
split.separator()
# Show addon user preferences
if is_enabled:
addon_preferences = userpref.addons[module_name].preferences
if addon_preferences is not None:
draw = getattr(addon_preferences, "draw", None)
if draw is not None:
addon_preferences_class = type(addon_preferences)
box_prefs = col_box.box()
box_prefs.label("Preferences:")
addon_preferences_class.layout = box_prefs
try:
draw(context)
except:
import traceback
traceback.print_exc()
box_prefs.label(text="Error (see console)", icon='ERROR')
del addon_preferences_class.layout
# Append missing scripts
# First collect scripts that are used but have no script file.
module_names = {mod.__name__ for mod, info in addons}

View File

@@ -70,7 +70,8 @@ class VIEW3D_HT_header(Header):
row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
# Occlude geometry
if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH')):
if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
(mode == 'WEIGHT_PAINT')):
row.prop(view, "use_occlude_geometry", text="")
# Proportional editing
@@ -1838,7 +1839,7 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
layout.separator()
if context.scene and 'FREESTYLE' in bpy.app.build_options:
if context.scene and bpy.app.build_options.freestyle:
layout.operator("mesh.mark_freestyle_edge").clear = False
layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
@@ -1884,7 +1885,7 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout.separator()
if context.scene and 'FREESTYLE' in bpy.app.build_options:
if context.scene and bpy.app.build_options.freestyle:
layout.operator("mesh.mark_freestyle_face").clear = False
layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True
@@ -2493,7 +2494,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
col.prop(mesh, "show_edge_bevel_weight", text="Bevel Weights")
col.prop(mesh, "show_edge_seams", text="Seams")
col.prop(mesh, "show_edge_sharp", text="Sharp")
if context.scene and 'FREESTYLE' in bpy.app.build_options:
if context.scene and bpy.app.build_options.freestyle:
col.prop(mesh, "show_freestyle_edge_marks", text="Freestyle Edge Marks")
col.prop(mesh, "show_freestyle_face_marks", text="Freestyle Face Marks")

View File

@@ -854,6 +854,36 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
class VIEW3D_PT_sculpt_topology(Panel, View3DPaintPanel):
bl_label = "Topology"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return (context.sculpt_object and context.tool_settings.sculpt)
def draw(self, context):
layout = self.layout
toolsettings = context.tool_settings
sculpt = toolsettings.sculpt
if context.sculpt_object.use_dynamic_topology_sculpting:
layout.operator("sculpt.dynamic_topology_toggle", icon='X', text="Disable Dynamic")
else:
layout.operator("sculpt.dynamic_topology_toggle", icon='SCULPT_DYNTOPO', text="Enable Dynamic")
col = layout.column()
col.active = context.sculpt_object.use_dynamic_topology_sculpting
col.prop(sculpt, "detail_size")
col.prop(sculpt, "use_smooth_shading")
col.prop(sculpt, "use_edge_collapse")
col.operator("sculpt.optimize")
col.separator()
col.prop(sculpt, "symmetrize_direction")
col.operator("sculpt.symmetrize")
class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
bl_label = "Options"
bl_options = {'DEFAULT_CLOSED'}
@@ -1167,7 +1197,8 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
if pe.type == 'PARTICLES':
if ob.particle_systems:
if len(ob.particle_systems) > 1:
layout.template_list(ob, "particle_systems", ob.particle_systems, "active_index", rows=2, maxrows=3)
layout.template_list("UI_UL_list", "", ob, "particle_systems",
ob.particle_systems, "active_index", rows=2, maxrows=3)
ptcache = ob.particle_systems.active.point_cache
else:
@@ -1176,7 +1207,8 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
ptcache = md.point_cache
if ptcache and len(ptcache.point_caches) > 1:
layout.template_list(ptcache, "point_caches", ptcache.point_caches, "active_index", rows=2, maxrows=3)
layout.template_list("UI_UL_list", "", ptcache, "point_caches", ptcache.point_caches, "active_index",
rows=2, maxrows=3)
if not pe.is_editable:
layout.label(text="Point cache must be baked")

View File

@@ -181,7 +181,7 @@ class BUILTIN_KSI_RotScale(KeyingSetInfo):
# ------------
# Location
# VisualLocation
class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
"""
Insert a keyframe on each of the location channels, taking into account
@@ -201,7 +201,7 @@ class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
generate = keyingsets_utils.RKS_GEN_location
# Rotation
# VisualRotation
class BUILTIN_KSI_VisualRot(KeyingSetInfo):
"""
Insert a keyframe on each of the rotation channels, taking into account
@@ -221,6 +221,26 @@ class BUILTIN_KSI_VisualRot(KeyingSetInfo):
generate = keyingsets_utils.RKS_GEN_rotation
# VisualScaling
class BUILTIN_KSI_VisualScaling(KeyingSetInfo):
"""
Insert a keyframe on each of the scale channels, taking into account
effects of constraints and relationships
"""
bl_label = "Visual Scaling"
bl_options = {'INSERTKEY_VISUAL'}
# poll - use predefined callback for selected bones/objects
poll = keyingsets_utils.RKS_POLL_selected_items
# iterator - use callback for selected bones/objects
iterator = keyingsets_utils.RKS_ITER_selected_item
# generator - use callback for location
generate = keyingsets_utils.RKS_GEN_scaling
# VisualLocRot
class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
"""
@@ -244,6 +264,80 @@ class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
# rotation
keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
# VisualLocScale
class BUILTIN_KSI_VisualLocScale(KeyingSetInfo):
"""
Insert a keyframe on each of the location and scaling channels,
taking into account effects of constraints and relationships
"""
bl_label = "Visual LocScale"
bl_options = {'INSERTKEY_VISUAL'}
# poll - use predefined callback for selected bones/objects
poll = keyingsets_utils.RKS_POLL_selected_items
# iterator - use callback for selected bones/objects
iterator = keyingsets_utils.RKS_ITER_selected_item
# generator
def generate(self, context, ks, data):
# location
keyingsets_utils.RKS_GEN_location(self, context, ks, data)
# scaling
keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
# VisualLocRotScale
class BUILTIN_KSI_VisualLocRotScale(KeyingSetInfo):
"""
Insert a keyframe on each of the location, rotation and scaling channels,
taking into account effects of constraints and relationships
"""
bl_label = "Visual LocRotScale"
bl_options = {'INSERTKEY_VISUAL'}
# poll - use predefined callback for selected bones/objects
poll = keyingsets_utils.RKS_POLL_selected_items
# iterator - use callback for selected bones/objects
iterator = keyingsets_utils.RKS_ITER_selected_item
# generator
def generate(self, context, ks, data):
# location
keyingsets_utils.RKS_GEN_location(self, context, ks, data)
# rotation
keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
# scaling
keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
# VisualRotScale
class BUILTIN_KSI_VisualRotScale(KeyingSetInfo):
"""
Insert a keyframe on each of the rotation and scaling channels,
taking into account effects of constraints and relationships
"""
bl_label = "Visual RotScale"
bl_options = {'INSERTKEY_VISUAL'}
# poll - use predefined callback for selected bones/objects
poll = keyingsets_utils.RKS_POLL_selected_items
# iterator - use callback for selected bones/objects
iterator = keyingsets_utils.RKS_ITER_selected_item
# generator
def generate(self, context, ks, data):
# rotation
keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
# scaling
keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
# ------------

View File

@@ -0,0 +1,6 @@
shader name()
{
}

View File

@@ -0,0 +1,18 @@
shader noise(
float Time = 1.0,
point Point = P,
output float Cell = 0.0,
output color Perlin = 0.8,
output color UPerlin = 0.8)
{
/* Cell Noise */
Cell = noise("cell", Point);
/* Perlin 4D Noise*/
Perlin = noise("perlin", Point, Time);
/* UPerlin 4D Noise*/
UPerlin = noise("uperlin", Point, Time);
}

View File

@@ -0,0 +1,11 @@
#include "oslutil.h"
shader wireframe(
float Line_Width = 2.0,
int Raster = 1,
output float Wire = 0.0)
{
Wire = wireframe("triangles", Line_Width, Raster);
}

View File

@@ -0,0 +1,78 @@
import bpy
class MATERIAL_UL_matslots_example(bpy.types.UIList):
# The draw_item function is called for each item of the collection that is visible in the list.
# data is the RNA object containing the collection,
# item is the current drawn item of the collection,
# icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
# have custom icons ID, which are not available as enum items).
# active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
# active item of the collection).
# active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
# index is index of the current item in the collection.
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
ob = data
slot = item
ma = slot.material
# 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), this will also make the row easily
# selectable in the list!
# We use icon_value of label, as our given icon is an integer value, not an enum ID.
layout.label(ma.name if ma else "", icon_value=icon)
# And now we can add other UI stuff...
# Here, we add nodes info if this material uses (old!) shading nodes.
if ma and not context.scene.render.use_shading_nodes:
manode = ma.active_node_material
if manode:
# The static method UILayout.icon returns the integer value of the icon ID "computed" for the given
# RNA object.
layout.label("Node %s" % manode.name, icon_value=layout.icon(manode))
elif ma.use_nodes:
layout.label("Node <none>")
else:
layout.label("")
# 'GRID' layout type should be as compact as possible (typically a single icon!).
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon_value=icon)
# And now we can use this list everywhere in Blender. Here is a small example panel.
class UIListPanelExample(bpy.types.Panel):
"""Creates a Panel in the Object properties window"""
bl_label = "UIList Panel"
bl_idname = "OBJECT_PT_ui_list_example"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
layout = self.layout
obj = context.object
# template_list now takes two new args.
# The first one is the identifier of the registered UIList to use (if you want only the default list,
# with no custom draw code, use "UI_UL_list").
layout.template_list("MATERIAL_UL_matslots_example", "", obj, "material_slots", obj, "active_material_index")
# The second one can usually be left as an empty string. It's an additional ID used to distinguish lists in case you
# use the same list several times in a given area.
layout.template_list("MATERIAL_UL_matslots_example", "compact", obj, "material_slots",
obj, "active_material_index", type='COMPACT')
def register():
bpy.utils.register_class(MATERIAL_UL_matslots_example)
bpy.utils.register_class(UIListPanelExample)
def unregister():
bpy.utils.unregister_class(MATERIAL_UL_matslots_example)
bpy.utils.unregister_class(UIListPanelExample)
if __name__ == "__main__":
register()