synched branch with trunk at revision 29109
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
82
release/scripts/modules/add_object_utils.py
Normal file
82
release/scripts/modules/add_object_utils.py
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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__ = ()
|
||||
|
||||
@@ -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'}
|
||||
|
||||
|
||||
@@ -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'}
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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 = ""
|
||||
|
||||
|
||||
55
release/scripts/templates/operator_modal_view3d.py
Normal file
55
release/scripts/templates/operator_modal_view3d.py
Normal 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)
|
||||
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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'}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user