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:
@@ -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 = "#~ "
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__ = ()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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="")
|
||||
|
||||
|
||||
@@ -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="")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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="")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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="")
|
||||
|
||||
@@ -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="")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
# ------------
|
||||
|
||||
|
||||
|
||||
6
release/scripts/templates_osl/empty_shader.osl
Normal file
6
release/scripts/templates_osl/empty_shader.osl
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
shader name()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
18
release/scripts/templates_osl/noise.osl
Normal file
18
release/scripts/templates_osl/noise.osl
Normal 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);
|
||||
}
|
||||
|
||||
11
release/scripts/templates_osl/wireframe.osl
Normal file
11
release/scripts/templates_osl/wireframe.osl
Normal 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);
|
||||
}
|
||||
|
||||
78
release/scripts/templates_py/ui_list.py
Normal file
78
release/scripts/templates_py/ui_list.py
Normal 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()
|
||||
Reference in New Issue
Block a user