synched branch with trunk at revision 29109

This commit is contained in:
Nick Samarin
2010-05-31 23:44:43 +00:00
parent 05b92f0fc9
commit d3d2e92fcc
210 changed files with 10935 additions and 8773 deletions

View File

@@ -1504,17 +1504,14 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tPolygonVertexIndex: ')
i=-1
for f in me.faces:
fi = [v for v in f.verts]
# fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3]
# fi = [v.index for v in f]
fi = f.verts[:]
# flip the last index, odd but it looks like
# this is how fbx tells one face from another
fi[-1] = -(fi[-1]+1)
# last index XORd w. -1 indicates end of face
fi[-1] = fi[-1] ^ -1
fi = tuple(fi)
if i==-1:
if len(fi) == 3: file.write('%i,%i,%i' % fi )
# if len(f) == 3: file.write('%i,%i,%i' % fi )
else: file.write('%i,%i,%i,%i' % fi )
i=0
else:
@@ -1522,10 +1519,26 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t')
i=0
if len(fi) == 3: file.write(',%i,%i,%i' % fi )
# if len(f) == 3: file.write(',%i,%i,%i' % fi )
else: file.write(',%i,%i,%i,%i' % fi )
i+=1
# write loose edges as faces.
for ed in me.edges:
if ed.loose:
ed_val = ed.verts[:]
ed_val = ed_val[0], ed_val[-1] ^ -1
if i==-1:
file.write('%i,%i' % ed_val)
i=0
else:
if i==13:
file.write('\n\t\t')
i=0
file.write(',%i,%i' % ed_val)
i+=1
file.write('\n\t\tEdges: ')
i=-1
for ed in me.edges:
@@ -2960,8 +2973,7 @@ Takes: {''')
# --------------------------- Footer
if world:
m = world.mist
has_mist = m.enabled
# has_mist = world.mode & 1
has_mist = m.use_mist
mist_intense = m.intensity
mist_start = m.start
mist_end = m.depth

View File

@@ -458,13 +458,11 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
pose_bone = pose_bones[bone_name]
pose_bone.rotation_mode = eul_order_lookup[tuple(bvh_node.rot_order)]
elif ROT_MODE == 'XYZ':
print(2)
elif ROT_MODE != 'QUATERNION':
for pose_bone in pose_bones:
pose_bone.rotation_mode = 'XYZ'
pose_bone.rotation_mode = ROT_MODE
else:
# Quats default
print(3)
pass
context.scene.update()
@@ -520,13 +518,13 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
lx, ly, lz, rx, ry, rz = bvh_node.anim_data[frame_current + 1]
if bvh_node.has_rot:
bone_rotation_matrix = Euler(rx, ry, rz).to_matrix().resize4x4()
bone_rotation_matrix = Euler((rx, ry, rz)).to_matrix().resize4x4()
bone_rotation_matrix = bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix
if ROT_MODE == 'QUATERNION':
pose_bone.rotation_quaternion = bone_rotation_matrix.to_quat()
else:
euler = bone_rotation_matrix.to_euler('XYZ', prev_euler[i]) # pose_bone.rotation_mode # TODO, XYZ default for now
euler = bone_rotation_matrix.to_euler(pose_bone.rotation_mode, prev_euler[i])
pose_bone.rotation_euler = euler
prev_euler[i] = euler
@@ -569,17 +567,17 @@ class BvhImporter(bpy.types.Operator):
loop = BoolProperty(name="Loop", description="Loop the animation playback", default=False)
rotate_mode = EnumProperty(items=(
('QUATERNION', "Quaternion", "Convert rotations to quaternions"),
# ('NATIVE', "Euler (Native)", "Use the rotation order defined in the BVH file"),
('NATIVE', "Euler (Native)", "Use the rotation order defined in the BVH file"),
('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
# ('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
# ('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
# ('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
# ('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
# ('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX")),
('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
),
name="Rotation",
description="Rotation conversion.",
default='QUATERNION')
default='NATIVE')
def execute(self, context):
# print("Selected: " + context.active_object.name)

View File

@@ -26,7 +26,7 @@ def RKS_POLL_selected_objects(ksi, context):
def RKS_POLL_selected_bones(ksi, context):
# we must be in Pose Mode, and there must be some bones selected
if (context.active_object) and (context.active_object.mode == 'POSE'):
if context.active_pose_bone or len(context.select_pose_bones):
if context.active_pose_bone or len(context.selected_pose_bones):
return True;
# nothing selected

View File

@@ -0,0 +1,82 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
import bpy
import mathutils
def add_object_align_init(context, operator):
if operator and operator.properties.is_property_set("location") and operator.properties.is_property_set("rotation"):
location = mathutils.TranslationMatrix(mathutils.Vector(operator.properties.location))
rotation = mathutils.Euler(operator.properties.rotation).to_matrix().resize4x4()
else:
# TODO, local view cursor!
location = mathutils.TranslationMatrix(context.scene.cursor_location)
if context.user_preferences.edit.object_align == 'VIEW' and context.space_data.type == 'VIEW_3D':
rotation = context.space_data.region_3d.view_matrix.rotation_part().invert().resize4x4()
else:
rotation = mathutils.Matrix()
# set the operator properties
if operator:
operator.properties.location = location.translation_part()
operator.properties.rotation = rotation.to_euler()
return location * rotation
def add_object_data(context, obdata, operator=None):
scene = context.scene
# ugh, could be made nicer
for ob in scene.objects:
ob.selected = False
obj_new = bpy.data.objects.new(obdata.name, obdata)
base = scene.objects.link(obj_new)
base.selected = True
if context.space_data and context.space_data.type == 'VIEW_3D':
base.layers_from_view(context.space_data)
obj_new.matrix = add_object_align_init(context, operator)
obj_act = scene.objects.active
if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type:
bpy.ops.object.mode_set(mode='OBJECT')
obj_act.selected = True
scene.update() # apply location
#scene.objects.active = obj_new
bpy.ops.object.join() # join into the active.
bpy.ops.object.mode_set(mode='EDIT')
else:
scene.objects.active = obj_new
if context.user_preferences.edit.enter_edit_mode:
bpy.ops.object.mode_set(mode='EDIT')
return base

View File

@@ -43,17 +43,11 @@ def _main():
## people need to explain how this is even a fix.
# _sys.path[:] = filter(None, _sys.path)
# a bit nasty but this prevents help() and input() from locking blender
# Ideally we could have some way for the console to replace sys.stdin but
# python would lock blender while waiting for a return value, not easy :|
if not app.debug:
_sys.stdin = None
# because of how the console works. we need our own help() pager func.
# replace the bold function because it adds crazy chars
import pydoc
pydoc.getpager = lambda: pydoc.plainpager
pydoc.Helper.getline = lambda self, prompt: None
pydoc.TextDoc.bold = lambda self, text: text

View File

@@ -38,6 +38,16 @@ class Context(StructRNA):
return new_context
class Group(bpy_types.ID):
__slots__ = ()
@property
def users_dupli_object(self):
"""The dupli group this group is used in, XXX, TODO, WHY DOESNT THIS WORK???"""
import bpy
return tuple(obj for obj in bpy.data.objects if self == obj.dupli_object)
class Object(bpy_types.ID):
__slots__ = ()
@@ -48,18 +58,16 @@ class Object(bpy_types.ID):
return tuple(child for child in bpy.data.objects if child.parent == self)
@property
def group_users(self):
def users_group(self):
"""The groups this object is in"""
import bpy
name = self.name
return tuple(group for group in bpy.data.groups if name in group.objects)
return tuple(group for group in bpy.data.groups if self in group.objects[:])
@property
def scene_users(self):
def users_scene(self):
"""The scenes this object is in"""
import bpy
name = self.name
return tuple(scene for scene in bpy.data.scenes if name in scene.objects)
return tuple(scene for scene in bpy.data.scenes if self in scene.objects[:])
class _GenericBone:
@@ -303,7 +311,7 @@ class Mesh(bpy_types.ID):
edge_face_count_dict = self.edge_face_count_dict
return [edge_face_count_dict.get(ed.key, 0) for ed in self.edges]
def edge_loops(self, faces=None, seams=()):
def edge_loops_from_faces(self, faces=None, seams=()):
"""
Edge loops defined by faces
@@ -314,7 +322,7 @@ class Mesh(bpy_types.ID):
return a list of edge key lists
[ [(0,1), (4, 8), (3,8)], ...]
optionaly, seams are edge keys that will be removed
return a list of edge vertex index lists
"""
OTHER_INDEX = 2, 3, 0, 1 # opposite face index
@@ -379,6 +387,71 @@ class Mesh(bpy_types.ID):
return edge_loops
def edge_loops_from_edges(self, edges=None):
"""
Edge loops defined by edges
Takes me.edges or a list of edges and returns the edge loops
return a list of vertex indices.
[ [1, 6, 7, 2], ...]
closed loops have matching start and end values.
"""
line_polys = []
# Get edges not used by a face
if edges is None:
edges = self.edges
if not hasattr(edges, "pop"):
edges = edges[:]
edge_dict= dict((ed.key, ed) for ed in self.edges if ed.selected)
while edges:
current_edge= edges.pop()
vert_end, vert_start = current_edge.verts[:]
line_poly = [vert_start, vert_end]
ok = True
while ok:
ok = False
#for i, ed in enumerate(edges):
i = len(edges)
while i:
i -= 1
ed = edges[i]
v1, v2 = ed.verts
if v1 == vert_end:
line_poly.append(v2)
vert_end = line_poly[-1]
ok = 1
del edges[i]
#break
elif v2 == vert_end:
line_poly.append(v1)
vert_end = line_poly[-1]
ok = 1
del edges[i]
#break
elif v1 == vert_start:
line_poly.insert(0, v2)
vert_start = line_poly[0]
ok = 1
del edges[i]
#break
elif v2 == vert_start:
line_poly.insert(0, v1)
vert_start = line_poly[0]
ok = 1
del edges[i]
#break
line_polys.append(line_poly)
return line_polys
class MeshEdge(StructRNA):
__slots__ = ()

View File

@@ -102,6 +102,10 @@ class AddTorus(bpy.types.Operator):
description="Total Interior Radius of the torus",
default=0.5, min=0.01, max=100.0)
# generic transform props
location = FloatVectorProperty(name="Location")
rotation = FloatVectorProperty(name="Rotation")
def execute(self, context):
props = self.properties
@@ -120,36 +124,10 @@ class AddTorus(bpy.types.Operator):
mesh.add_geometry(int(len(verts_loc) / 3), 0, int(len(faces) / 4))
mesh.verts.foreach_set("co", verts_loc)
mesh.faces.foreach_set("verts_raw", faces)
scene = context.scene
# ugh
for ob in scene.objects:
ob.selected = False
mesh.update()
ob_new = bpy.data.objects.new("Torus", mesh)
scene.objects.link(ob_new)
ob_new.selected = True
ob_new.location = scene.cursor_location
obj_act = scene.objects.active
if obj_act and obj_act.mode == 'EDIT':
bpy.ops.object.mode_set(mode='OBJECT')
obj_act.selected = True
scene.update() # apply location
#scene.objects.active = ob_new
bpy.ops.object.join() # join into the active.
bpy.ops.object.mode_set(mode='EDIT')
else:
scene.objects.active = ob_new
if context.user_preferences.edit.enter_edit_mode:
bpy.ops.object.mode_set(mode='EDIT')
import add_object_utils
add_object_utils.add_object_data(context, mesh, operator=self)
return {'FINISHED'}

View File

@@ -85,7 +85,7 @@ def execute(context):
sc = context.space_data
try:
line = sc.history[-1].line
line_object = sc.history[-1]
except:
return {'CANCELLED'}
@@ -102,13 +102,26 @@ def execute(context):
sys.stdout = stdout
sys.stderr = stderr
# run the console
if not line.strip():
line_exec = '\n' # executes a multiline statement
else:
line_exec = line
# dont allow the stdin to be used, can lock blender.
stdin_backup = sys.stdin
sys.stdin = None
is_multiline = console.push(line_exec)
# incase exception happens
line = "" # incase of encodingf error
is_multiline = False
try:
line = line_object.line
# run the console, "\n" executes a multiline statement
line_exec = line if line.strip() else "\n"
is_multiline = console.push(line_exec)
except:
# unlikely, but this can happen with unicode errors for example.
import traceback
stderr.write(traceback.format_exc())
stdout.seek(0)
stderr.seek(0)
@@ -144,6 +157,9 @@ def execute(context):
if output_err:
add_scrollback(output_err, 'ERROR')
# restore the stdin
sys.stdin = stdin_backup
return {'FINISHED'}
@@ -154,23 +170,37 @@ def autocomplete(context):
console = get_console(hash(context.region))[0]
current_line = sc.history[-1]
line = current_line.line
if not console:
return {'CANCELLED'}
if sc.console_type != 'PYTHON':
return {'CANCELLED'}
# This function isnt aware of the text editor or being an operator
# just does the autocomp then copy its results back
current_line.line, current_line.current_character, scrollback = \
intellisense.expand(
line=current_line.line,
cursor=current_line.current_character,
namespace=console.locals,
private=bpy.app.debug)
# dont allow the stdin to be used, can lock blender.
# note: unlikely stdin would be used for autocomp. but its possible.
stdin_backup = sys.stdin
sys.stdin = None
scrollback = ""
scrollback_error = ""
try:
current_line = sc.history[-1]
line = current_line.line
# This function isnt aware of the text editor or being an operator
# just does the autocomp then copy its results back
current_line.line, current_line.current_character, scrollback = \
intellisense.expand(
line=current_line.line,
cursor=current_line.current_character,
namespace=console.locals,
private=bpy.app.debug)
except:
# unlikely, but this can happen with unicode errors for example.
# or if the api attribute access its self causes an error.
import traceback
scrollback_error = traceback.format_exc()
# Separate automplete output by command prompts
if scrollback != '':
@@ -182,6 +212,12 @@ def autocomplete(context):
if scrollback:
add_scrollback(scrollback, 'INFO')
if scrollback_error:
add_scrollback(scrollback_error, 'ERROR')
# restore the stdin
sys.stdin = stdin_backup
context.area.tag_redraw()
return {'FINISHED'}

View File

@@ -507,6 +507,26 @@ class MakeDupliFace(bpy.types.Operator):
return {'FINISHED'}
class IsolateTypeRender(bpy.types.Operator):
'''Select object matching a naming pattern'''
bl_idname = "object.isolate_type_render"
bl_label = "Isolate Render Selection"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
act_type = context.object.type
for obj in context.visible_objects:
if obj.selected:
obj.restrict_render = False
else:
if obj.type == act_type:
obj.restrict_render = True
return {'FINISHED'}
classes = [
SelectPattern,
SelectCamera,
@@ -514,6 +534,7 @@ classes = [
SubdivisionSet,
ShapeTransfer,
JoinUVs,
IsolateTypeRender,
MakeDupliFace]

View File

@@ -94,11 +94,14 @@ class SequencerCutMulticam(bpy.types.Operator):
s = context.scene.sequence_editor.active_strip
if s.multicam_source == camera:
return {'FINISHED'}
if not s.selected:
s.selected = True
cfra = context.scene.frame_current
bpy.ops.sequencer.cut(frame=cfra, type='HARD', side='RIGHT')
bpy.ops.sequencer.cut(frame=cfra, type='SOFT', side='RIGHT')
for s in context.scene.sequence_editor.sequences_all:
if s.selected and s.type == 'MULTICAM' and s.frame_final_start <= cfra and cfra < s.frame_final_end:
context.scene.sequence_editor.active_strip = s
@@ -135,7 +138,6 @@ def register():
register(SequencerCutMulticam)
register(SequencerDeinterlaceSelectedMovies)
def unregister():
unregister = bpy.types.unregister
@@ -143,5 +145,7 @@ def unregister():
unregister(SequencerCutMulticam)
unregister(SequencerDeinterlaceSelectedMovies)
if __name__ == "__main__":
register()

View File

@@ -167,18 +167,34 @@ class ExportUVLayout(bpy.types.Operator):
fw('1 setlinewidth\n')
fw('1 setlinejoin\n')
fw('1 setlinecap\n')
fw('/DRAW {')
# can remove from here to next comment to disable filling, aparently alpha is not supported
fw('gsave\n')
fw('0.7 setgray\n')
fw('fill\n')
fw('grestore\n')
fw('0 setgray\n')
# remove to here
fw('stroke\n')
fw('} def\n')
fw('newpath\n')
firstline = True
for i, uvs in self._face_uv_iter(context):
for j, uv in enumerate(uvs):
x, y = uv[0], uv[1]
if j == 0:
if not firstline:
fw('closepath\n')
fw('DRAW\n')
fw('newpath\n')
firstline = False
fw('%.5f %.5f moveto\n' % (x * image_width, y * image_height))
else:
fw('%.5f %.5f lineto\n' % (x * image_width, y * image_height))
fw('closepath\n')
fw('stroke\n')
fw('DRAW\n')
fw('showpage\n')
fw('%%EOF\n')
@@ -203,7 +219,7 @@ def register():
bpy.types.IMAGE_MT_uvs.append(menu_func)
def unreguster():
def unregister():
bpy.types.unregister(ExportUVLayout)
bpy.types.IMAGE_MT_uvs.remove(menu_func)

View File

@@ -180,7 +180,7 @@ def extend(obj, operator, EXTEND_MODE):
#SEAM = me.edges.seam
if EXTEND_MODE == 'LENGTH':
edge_loops = me.edge_loops(face_sel, [ed.key for ed in me.edges if ed.seam])
edge_loops = me.edge_loops_from_faces(face_sel, [ed.key for ed in me.edges if ed.seam])
me_verts = me.verts
for loop in edge_loops:
looplen = [0.0]

View File

@@ -418,7 +418,7 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
class WM_OT_url_open(bpy.types.Operator):
"Open the Blender Wiki in the Webbrowser"
"Open a website in the Webbrowser"
bl_idname = "wm.url_open"
bl_label = ""

View File

@@ -0,0 +1,55 @@
from mathutils import Vector
from bpy.props import FloatVectorProperty
class ViewOperator(bpy.types.Operator):
'''Translate the view using mouse events.'''
bl_idname = "view3d.modal_operator"
bl_label = "Simple View Operator"
offset = FloatVectorProperty(name="Offset", size=3)
def execute(self, context):
v3d = context.space_data
rv3d = v3d.region_3d
rv3d.view_location = self._initial_location + Vector(self.properties.offset)
def modal(self, context, event):
v3d = context.space_data
rv3d = v3d.region_3d
if event.type == 'MOUSEMOVE':
self.properties.offset = (self._initial_mouse - Vector((event.mouse_x, event.mouse_y, 0.0))) * 0.02
self.execute(context)
elif event.type == 'LEFTMOUSE':
return {'FINISHED'}
elif event.type in ('RIGHTMOUSE', 'ESC'):
rv3d.view_location = self._initial_location
return {'CANCELLED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
if context.space_data.type == 'VIEW_3D':
v3d = context.space_data
rv3d = v3d.region_3d
context.manager.add_modal_handler(self)
if rv3d.view_perspective == 'CAMERA':
rv3d.view_perspective = 'PERSP'
self._initial_mouse = Vector((event.mouse_x, event.mouse_y, 0.0))
self._initial_location = rv3d.view_location.copy()
return {'RUNNING_MODAL'}
else:
self.report({'WARNING'}, "Active space must be a View3d")
return {'CANCELLED'}
bpy.types.register(ViewOperator)

View File

@@ -61,6 +61,8 @@ class MotionPathButtonsPanel(bpy.types.Panel):
col.label(text="Display:")
col.prop(mps, "show_frame_numbers", text="Frame Numbers")
col.prop(mps, "highlight_keyframes", text="Keyframes")
if bones:
col.prop(mps, "search_all_action_keyframes", text="+ Non-Grouped Keyframes")
col.prop(mps, "show_keyframe_numbers", text="Keyframe Numbers")

View File

@@ -24,7 +24,7 @@ narrowui = bpy.context.user_preferences.view.properties_width_check
class LAMP_MT_sunsky_presets(bpy.types.Menu):
bl_label = "Render Presets"
bl_label = "Sun & Sky Presets"
preset_subdir = "sunsky"
preset_operator = "script.execute_preset"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}

View File

@@ -182,7 +182,7 @@ class OBJECT_PT_groups(ObjectButtonsPanel):
col.prop(group, "dupli_offset", text="")
prop = col.operator("wm.context_set_value", text="From Cursor")
prop.path = "object.group_users[%d].dupli_offset" % index
prop.path = "object.users_group[%d].dupli_offset" % index
prop.value = value
index += 1

View File

@@ -76,7 +76,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
else:
layout.prop_object(con, "subtarget", con.target.data, "bones", text="")
if con.type in ('COPY_LOCATION', 'STRETCH_TO', 'TRACK_TO'):
if con.type in ('COPY_LOCATION', 'STRETCH_TO', 'TRACK_TO', 'PIVOT'):
row = layout.row()
row.label(text="Head/Tail:")
row.prop(con, "head_tail", text="")
@@ -730,6 +730,22 @@ class ConstraintButtonsPanel(bpy.types.Panel):
col.prop(con, "xz_scaling_mode", text="")
col.prop(con, "use_curve_radius")
def PIVOT(self, context, layout, con, wide_ui):
self.target_template(layout, con, wide_ui)
if con.target:
col = layout.column()
col.prop(con, "offset", text="Pivot Offset")
else:
col = layout.column()
col.prop(con, "use_relative_position")
if con.use_relative_position:
col.prop(con, "offset", text="Relative Pivot Point")
else:
col.prop(con, "offset", text="Absolute Pivot Point")
col = layout.column()
col.prop(con, "enabled_rotation_range", text="Pivot When")
class OBJECT_PT_constraints(ConstraintButtonsPanel):
bl_label = "Object Constraints"

View File

@@ -705,12 +705,6 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
sub = split.column()
sub.prop(part, "velocity_length")
elif part.ren_as == 'PATH':
if part.type != 'HAIR' and part.physics_type != 'KEYED' and (psys.point_cache.baked is False):
box = layout.box()
box.label(text="Baked or keyed particles needed for correct rendering.")
return
sub.prop(part, "render_strand")
subsub = sub.column()
subsub.active = (part.render_strand is False)
@@ -862,11 +856,6 @@ class PARTICLE_PT_draw(ParticleButtonsPanel):
path = (part.ren_as == 'PATH' and part.draw_as == 'RENDER') or part.draw_as == 'PATH'
if path and part.type != 'HAIR' and part.physics_type != 'KEYED' and psys.point_cache.baked is False:
box = layout.box()
box.label(text="Baked or keyed particles needed for correct drawing.")
return
row = layout.row()
row.prop(part, "display", slider=True)
if part.draw_as != 'RENDER' or part.ren_as == 'HALO':

View File

@@ -187,14 +187,14 @@ class RENDER_PT_shading(RenderButtonsPanel):
split = layout.split()
col = split.column()
col.prop(rd, "render_textures", text="Textures")
col.prop(rd, "render_shadows", text="Shadows")
col.prop(rd, "render_sss", text="Subsurface Scattering")
col.prop(rd, "render_envmaps", text="Environment Map")
col.prop(rd, "use_textures", text="Textures")
col.prop(rd, "use_shadows", text="Shadows")
col.prop(rd, "use_sss", text="Subsurface Scattering")
col.prop(rd, "use_envmaps", text="Environment Map")
if wide_ui:
col = split.column()
col.prop(rd, "render_raytracing", text="Ray Tracing")
col.prop(rd, "use_raytracing", text="Ray Tracing")
col.prop(rd, "color_management")
col.prop(rd, "alpha_mode", text="Alpha")
@@ -233,7 +233,7 @@ class RENDER_PT_performance(RenderButtonsPanel):
sub.active = rd.use_compositing
sub.prop(rd, "free_image_textures")
sub = col.column()
sub.active = rd.render_raytracing
sub.active = rd.use_raytracing
sub.label(text="Acceleration structure:")
sub.prop(rd, "raytrace_structure", text="")
if rd.raytrace_structure == 'OCTREE':

View File

@@ -199,6 +199,18 @@ class INFO_MT_mesh_add(bpy.types.Menu):
layout.operator("mesh.primitive_grid_add", icon='MESH_GRID', text="Grid")
layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey")
class INFO_MT_curve_add(bpy.types.Menu):
bl_idname = "INFO_MT_curve_add"
bl_label = "Curve"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("curve.primitive_bezier_curve_add", icon='CURVE_BEZCURVE', text="Bezier")
layout.operator("curve.primitive_bezier_circle_add", icon='CURVE_BEZCIRCLE', text="Circle")
layout.operator("curve.primitive_nurbs_curve_add", icon='CURVE_NCURVE', text="Nurbs Curve")
layout.operator("curve.primitive_nurbs_circle_add", icon='CURVE_NCIRCLE', text="Nurbs Circle")
layout.operator("curve.primitive_nurbs_path_add", icon='CURVE_PATH', text="Path")
class INFO_MT_armature_add(bpy.types.Menu):
bl_idname = "INFO_MT_armature_add"
@@ -221,7 +233,8 @@ class INFO_MT_add(bpy.types.Menu):
#layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
layout.menu("INFO_MT_mesh_add", icon='OUTLINER_OB_MESH')
layout.operator_menu_enum("object.curve_add", "type", text="Curve", icon='OUTLINER_OB_CURVE')
#layout.operator_menu_enum("object.curve_add", "type", text="Curve", icon='OUTLINER_OB_CURVE')
layout.menu("INFO_MT_curve_add", icon='OUTLINER_OB_CURVE')
layout.operator_menu_enum("object.surface_add", "type", text="Surface", icon='OUTLINER_OB_SURFACE')
layout.operator_menu_enum("object.metaball_add", "type", text="Metaball", icon='OUTLINER_OB_META')
layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
@@ -245,7 +258,7 @@ class INFO_MT_add(bpy.types.Menu):
layout.operator_context = 'INVOKE_DEFAULT'
layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_EMPTY')
else:
layout.operator_menu_enum("object.group_instance_add", "type", text="Group Instance", icon='OUTLINER_OB_EMPTY')
layout.operator_menu_enum("object.group_instance_add", "group", text="Group Instance", icon='OUTLINER_OB_EMPTY')
class INFO_MT_game(bpy.types.Menu):
@@ -297,19 +310,19 @@ class INFO_MT_help(bpy.types.Menu):
def draw(self, context):
layout = self.layout
layout.operator("help.manual", icon='HELP')
layout.operator("help.release_logs", icon='URL')
layout.operator("wm.url_open", text="Manual", icon='HELP').url = 'http://wiki.blender.org/index.php/Doc:Manual'
layout.operator("wm.url_open", text="Release Log", icon='URL').url = 'http://www.blender.org/development/release-logs/blender-250/'
layout.separator()
layout.operator("help.blender_website", icon='URL')
layout.operator("help.blender_eshop", icon='URL')
layout.operator("help.developer_community", icon='URL')
layout.operator("help.user_community", icon='URL')
layout.operator("wm.url_open", text="Blender Website", icon='URL').url = 'http://www.blender.org/'
layout.operator("wm.url_open", text="Blender e-Shop", icon='URL').url = 'http://www.blender.org/e-shop'
layout.operator("wm.url_open", text="Developer Community", icon='URL').url = 'http://www.blender.org/community/get-involved/'
layout.operator("wm.url_open", text="User Community", icon='URL').url = 'http://www.blender.org/community/user-community/'
layout.separator()
layout.operator("help.report_bug", icon='URL')
layout.operator("wm.url_open", text="Report a Bug", icon='URL').url = 'http://projects.blender.org/tracker/?atid=498&group_id=9&func=browse'
layout.separator()
layout.operator("help.python_api", icon='URL')
layout.operator("wm.url_open", text="Python API Reference", icon='URL').url = 'http://www.blender.org/documentation/250PythonDoc/contents.html'
layout.operator("help.operator_cheat_sheet")
layout.separator()
layout.operator("wm.splash")
@@ -318,70 +331,6 @@ class INFO_MT_help(bpy.types.Menu):
# Help operators
class HelpOperator(bpy.types.Operator):
def execute(self, context):
import webbrowser
webbrowser.open(self._url)
return {'FINISHED'}
class HELP_OT_manual(HelpOperator):
'''The Blender Wiki manual'''
bl_idname = "help.manual"
bl_label = "Manual"
_url = 'http://wiki.blender.org/index.php/Doc:Manual'
class HELP_OT_release_logs(HelpOperator):
'''Information about the changes in this version of Blender'''
bl_idname = "help.release_logs"
bl_label = "Release Log"
_url = 'http://www.blender.org/development/release-logs/blender-250/'
class HELP_OT_blender_website(HelpOperator):
'''The official Blender website'''
bl_idname = "help.blender_website"
bl_label = "Blender Website"
_url = 'http://www.blender.org/'
class HELP_OT_blender_eshop(HelpOperator):
'''Buy official Blender resources and merchandise online'''
bl_idname = "help.blender_eshop"
bl_label = "Blender e-Shop"
_url = 'http://www.blender.org/e-shop'
class HELP_OT_developer_community(HelpOperator):
'''Get involved with Blender development'''
bl_idname = "help.developer_community"
bl_label = "Developer Community"
_url = 'http://www.blender.org/community/get-involved/'
class HELP_OT_user_community(HelpOperator):
'''Get involved with other Blender users'''
bl_idname = "help.user_community"
bl_label = "User Community"
_url = 'http://www.blender.org/community/user-community/'
class HELP_OT_report_bug(HelpOperator):
'''Report a bug in the Blender bug tracker'''
bl_idname = "help.report_bug"
bl_label = "Report a Bug"
_url = 'http://projects.blender.org/tracker/?atid=498&group_id=9&func=browse'
class HELP_OT_python_api(HelpOperator):
'''Reference for operator and data Python API'''
bl_idname = "help.python_api"
bl_label = "Python API Reference"
_url = 'http://www.blender.org/documentation/250PythonDoc/contents.html'
class HELP_OT_operator_cheat_sheet(bpy.types.Operator):
bl_idname = "help.operator_cheat_sheet"
bl_label = "Operator Cheat Sheet (new textblock)"
@@ -416,19 +365,12 @@ classes = [
INFO_MT_file_external_data,
INFO_MT_add,
INFO_MT_mesh_add,
INFO_MT_curve_add,
INFO_MT_armature_add,
INFO_MT_game,
INFO_MT_render,
INFO_MT_help,
HELP_OT_manual,
HELP_OT_release_logs,
HELP_OT_blender_website,
HELP_OT_blender_eshop,
HELP_OT_developer_community,
HELP_OT_user_community,
HELP_OT_report_bug,
HELP_OT_python_api,
HELP_OT_operator_cheat_sheet]

View File

@@ -457,6 +457,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel):
row = layout.row(align=True)
sub = row.row()
sub.scale_x = 2.0
if not context.screen.animation_playing:
sub.operator("screen.animation_play", text="", icon='PLAY')
else:
@@ -665,6 +666,12 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel):
row.prop(strip.sound, "caching")
layout.prop(strip, "volume")
layout.prop(strip, "attenuation")
col = layout.column(align=True)
col.label(text="Trim Duration:")
col.prop(strip, "animation_start_offset", text="Start")
col.prop(strip, "animation_end_offset", text="End")
class SEQUENCER_PT_scene(SequencerButtonsPanel):

View File

@@ -554,6 +554,10 @@ class USERPREF_PT_theme(bpy.types.Panel):
ui = theme.user_interface.wcol_scroll
col.label(text="Scroll Bar:")
ui_items_general(col, ui)
ui = theme.user_interface.wcol_progress
col.label(text="Progress Bar:")
ui_items_general(col, ui)
ui = theme.user_interface.wcol_list_item
col.label(text="List Item:")
@@ -1187,7 +1191,7 @@ class USERPREF_PT_addons(bpy.types.Panel):
# If there are Infos or UI is expanded
if info["expanded"]:
row.operator("wm.addon_expand", icon="TRIA_DOWN").module = module_name
elif info["author"] or info["version"] or info["url"] or info["location"]:
elif info["author"] or info["version"] or info["wiki_url"] or info["location"]:
row.operator("wm.addon_expand", icon="TRIA_RIGHT").module = module_name
else:
# Else, block UI
@@ -1216,12 +1220,19 @@ class USERPREF_PT_addons(bpy.types.Panel):
split = column.row().split(percentage=0.15)
split.label(text='Description:')
split.label(text=info["description"])
if info["url"]:
if info["wiki_url"] or info["tracker_url"]:
split = column.row().split(percentage=0.15)
split.label(text="Internet:")
split.operator("wm.addon_links", text="Link to the Wiki").link = info["url"]
split.separator()
split.separator()
if info["wiki_url"]:
split.operator("wm.url_open", text="Link to the Wiki", icon='HELP').url = info["wiki_url"]
if info["tracker_url"]:
split.operator("wm.url_open", text="Report a Bug", icon='URL').url = info["tracker_url"]
if info["wiki_url"] and info["tracker_url"]:
split.separator()
else:
split.separator()
split.separator()
# Append missing scripts
# First collect scripts that are used but have no script file.
@@ -1245,7 +1256,7 @@ class USERPREF_PT_addons(bpy.types.Panel):
from bpy.props import *
def addon_info_get(mod, info_basis={"name": "", "author": "", "version": "", "blender": "", "location": "", "description": "", "url": "", "category": "", "expanded": False}):
def addon_info_get(mod, info_basis={"name": "", "author": "", "version": "", "blender": "", "location": "", "description": "", "wiki_url": "", "tracker_url": "", "category": "", "expanded": False}):
addon_info = getattr(mod, "bl_addon_info", {})
# avoid re-initializing
@@ -1410,19 +1421,6 @@ class WM_OT_addon_expand(bpy.types.Operator):
return {'FINISHED'}
class WM_OT_addon_links(bpy.types.Operator):
"Open the Blender Wiki in the Webbrowser"
bl_idname = "wm.addon_links"
bl_label = ""
link = StringProperty(name="Link", description="Link to open")
def execute(self, context):
import webbrowser
webbrowser.open(self.properties.link)
return {'FINISHED'}
classes = [
USERPREF_HT_header,
USERPREF_PT_tabs,
@@ -1440,8 +1438,7 @@ classes = [
WM_OT_addon_enable,
WM_OT_addon_disable,
WM_OT_addon_install,
WM_OT_addon_expand,
WM_OT_addon_links]
WM_OT_addon_expand]
def register():

View File

@@ -32,14 +32,13 @@ class VIEW3D_HT_header(bpy.types.Header):
obj = context.active_object
toolsettings = context.tool_settings
row = layout.row()
row = layout.row(align=True)
row.template_header()
sub = row.row(align=True)
# Menus
if context.area.show_menus:
sub = row.row(align=True)
sub.menu("VIEW3D_MT_view")
# Select Menu
@@ -54,6 +53,7 @@ class VIEW3D_HT_header(bpy.types.Header):
else:
sub.menu("VIEW3D_MT_object")
row = layout.row()
row.template_header_3D()
# do in C for now since these buttons cant be both toggle AND exclusive.
@@ -675,6 +675,7 @@ class VIEW3D_MT_object(bpy.types.Menu):
layout.menu("VIEW3D_MT_object_track")
layout.menu("VIEW3D_MT_object_group")
layout.menu("VIEW3D_MT_object_constraints")
layout.menu("VIEW3D_MT_object_game_properties")
layout.separator()
@@ -706,14 +707,13 @@ class VIEW3D_MT_object_specials(bpy.types.Menu):
def poll(self, context):
# add more special types
obj = context.object
return bool(obj and obj.type == 'LAMP')
return context.object
def draw(self, context):
layout = self.layout
obj = context.object
if obj and obj.type == 'LAMP':
if obj.type == 'LAMP':
layout.operator_context = 'INVOKE_REGION_WIN'
props = layout.operator("wm.context_modal_mouse", text="Spot Size")
@@ -736,6 +736,10 @@ class VIEW3D_MT_object_specials(bpy.types.Menu):
props.path_item = "data.shadow_buffer_clip_end"
props.input_scale = 0.05
layout.separator()
props = layout.operator("object.isolate_type_render")
class VIEW3D_MT_object_apply(bpy.types.Menu):
bl_label = "Apply"
@@ -793,6 +797,7 @@ class VIEW3D_MT_object_constraints(bpy.types.Menu):
layout = self.layout
layout.operator("object.constraint_add_with_targets")
layout.operator("object.constraints_copy")
layout.operator("object.constraints_clear")
@@ -840,6 +845,17 @@ class VIEW3D_MT_make_links(bpy.types.Menu):
layout.operator_enums("object.make_links_data", "type") # inline
class VIEW3D_MT_object_game_properties(bpy.types.Menu):
bl_label = "Game Properties"
def draw(self, context):
layout = self.layout
layout.operator("object.game_property_copy", text="Replace").operation="REPLACE"
layout.operator("object.game_property_copy", text="Merge").operation="MERGE"
# layout.operator("object.game_property_copy").operation="CLEAR" doesn't really belong as part of copy...
layout.operator_menu_enum("object.game_property_copy", "property", text="Copy...")
# ********** Vertex paint menu **********
@@ -1145,6 +1161,7 @@ class VIEW3D_MT_pose_constraints(bpy.types.Menu):
layout = self.layout
layout.operator("pose.constraint_add_with_targets", text="Add (With Targets)...")
layout.operator("pose.constraints_copy")
layout.operator("pose.constraints_clear")
@@ -2205,6 +2222,7 @@ classes = [
VIEW3D_MT_object_track,
VIEW3D_MT_object_group,
VIEW3D_MT_object_constraints,
VIEW3D_MT_object_game_properties,
VIEW3D_MT_object_showhide,
VIEW3D_MT_make_single_user,
VIEW3D_MT_make_links,