Merged changes in the trunk up to revision 54110.

Conflicts resolved:
source/blender/blenfont/SConscript
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/intern/rna_scene.c
This commit is contained in:
2013-01-26 23:49:13 +00:00
748 changed files with 31619 additions and 23270 deletions

View File

@@ -35,6 +35,7 @@ _modules = [
"object_randomize_transform",
"object_quick_effects",
"presets",
"rigidbody",
"screen_play_rendered_anim",
"sequencer",
"uvcalc_follow_active",

View File

@@ -22,6 +22,7 @@ import bpy
from bpy.types import Operator
from bpy.props import BoolProperty, EnumProperty, StringProperty
# Base class for node 'Add' operators
class NodeAddOperator():
@staticmethod
@@ -78,8 +79,9 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
use_transform = BoolProperty(
name="Use Transform",
description="Start transform operator after inserting the node",
default = False,
default=False,
)
def execute(self, context):
node = self.create_node(context, self.type)

View File

@@ -110,6 +110,12 @@ class SelectCamera(Operator):
bl_label = "Select Camera"
bl_options = {'REGISTER', 'UNDO'}
extend = BoolProperty(
name="Extend",
description="Extend the selection",
default=False
)
def execute(self, context):
scene = context.scene
view = context.space_data
@@ -123,6 +129,8 @@ class SelectCamera(Operator):
elif camera.name not in scene.objects:
self.report({'WARNING'}, "Active camera is not in this scene")
else:
if not self.extend:
bpy.ops.object.select_all(action='DESELECT')
context.scene.objects.active = camera
camera.select = True
return {'FINISHED'}
@@ -297,7 +305,7 @@ class ShapeTransfer(Operator):
('RELATIVE_EDGE',
"Relative Edge",
"Calculate relative position (using edges)",
),
),
),
name="Transformation Mode",
description="Relative shape positions to the new shape method",
@@ -674,7 +682,7 @@ class TransformsToDeltasAnim(Operator):
"scale" : "delta_scale"
}
DELTA_PATHS = STANDARD_TO_DELTA_PATHS.values()
# try to apply on each selected object
success = False
for obj in context.selected_editable_objects:
@@ -684,7 +692,7 @@ class TransformsToDeltasAnim(Operator):
"No animation data to convert on object: %r" %
obj.name)
continue
# first pass over F-Curves: ensure that we don't have conflicting
# transforms already (e.g. if this was applied already) [#29110]
existingFCurves = {}
@@ -700,7 +708,7 @@ class TransformsToDeltasAnim(Operator):
else:
# non-transform - ignore
continue
# a delta path like this for the same index shouldn't
# exist already, otherwise we've got a conflict
if dpath in existingFCurves:
@@ -708,8 +716,9 @@ class TransformsToDeltasAnim(Operator):
if fcu.array_index in existingFCurves[dpath]:
# conflict
self.report({'ERROR'},
"Object '%r' already has '%r' F-Curve(s). Remove these before trying again" %
(obj.name, dpath))
"Object '%r' already has '%r' F-Curve(s). "
"Remove these before trying again" %
(obj.name, dpath))
return {'CANCELLED'}
else:
# no conflict here
@@ -717,8 +726,7 @@ class TransformsToDeltasAnim(Operator):
else:
# no conflict yet
existingFCurves[dpath] = [fcu.array_index]
# if F-Curve uses standard transform path
# just append "delta_" to this path
for fcu in adt.action.fcurves:
@@ -758,7 +766,7 @@ class DupliOffsetFromCursor(Operator):
@classmethod
def poll(cls, context):
return context.active_object is not None
return (context.active_object is not None)
def execute(self, context):
scene = context.scene

View File

@@ -114,14 +114,15 @@ def GlobalBB_HQ(obj):
return Vector((left, front, up)), Vector((right, back, down))
def align_objects(align_x,
def align_objects(context,
align_x,
align_y,
align_z,
align_mode,
relative_to,
bb_quality):
cursor = bpy.context.scene.cursor_location
cursor = context.scene.cursor_location
Left_Front_Up_SEL = [0.0, 0.0, 0.0]
Right_Back_Down_SEL = [0.0, 0.0, 0.0]
@@ -130,7 +131,7 @@ def align_objects(align_x,
objs = []
for obj in bpy.context.selected_objects:
for obj in context.selected_objects:
matrix_world = obj.matrix_world.copy()
bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
objs.append((obj, bb_world))
@@ -150,7 +151,7 @@ def align_objects(align_x,
# Active Center
if obj == bpy.context.active_object:
if obj == context.active_object:
center_active_x = (Left_Front_Up[0] + Right_Back_Down[0]) / 2.0
center_active_y = (Left_Front_Up[1] + Right_Back_Down[1]) / 2.0
@@ -386,7 +387,8 @@ class AlignObjects(Operator):
def execute(self, context):
align_axis = self.align_axis
ret = align_objects('X' in align_axis,
ret = align_objects(context,
'X' in align_axis,
'Y' in align_axis,
'Z' in align_axis,
self.align_mode,

View File

@@ -72,7 +72,7 @@ class QuickFur(Operator):
)
def execute(self, context):
fake_context = bpy.context.copy()
fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
if obj.type == 'MESH']
@@ -161,7 +161,7 @@ class QuickExplode(Operator):
)
def execute(self, context):
fake_context = bpy.context.copy()
fake_context = context.copy()
obj_act = context.active_object
if obj_act is None or obj_act.type != 'MESH':
@@ -311,7 +311,7 @@ class QuickSmoke(Operator):
)
def execute(self, context):
fake_context = bpy.context.copy()
fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
if obj.type == 'MESH']
min_co = Vector((100000.0, 100000.0, 100000.0))
@@ -432,7 +432,7 @@ class QuickFluid(Operator):
)
def execute(self, context):
fake_context = bpy.context.copy()
fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
if (obj.type == 'MESH' and not 0.0 in obj.dimensions)]
min_co = Vector((100000, 100000, 100000))

View File

@@ -23,7 +23,8 @@ from bpy.types import Operator
from mathutils import Vector
def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min):
def randomize_selected(context, seed, delta,
loc, rot, scale, scale_even, scale_min):
import random
from random import uniform
@@ -33,7 +34,7 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min):
def rand_vec(vec_range):
return Vector(uniform(-val, val) for val in vec_range)
for obj in bpy.context.selected_objects:
for obj in context.selected_objects:
if loc:
if delta:
@@ -180,6 +181,7 @@ class RandomizeLocRotSize(Operator):
#scale_min = self.scale_min
scale_min = 0
randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min)
randomize_selected(context, seed, delta,
loc, rot, scale, scale_even, scale_min)
return {'FINISHED'}

View File

@@ -320,13 +320,13 @@ class AddPresetFluid(AddPresetBase, Operator):
preset_menu = "FLUID_MT_presets"
preset_defines = [
"fluid = bpy.context.fluid"
]
"fluid = bpy.context.fluid"
]
preset_values = [
"fluid.settings.viscosity_base",
"fluid.settings.viscosity_exponent",
]
"fluid.settings.viscosity_base",
"fluid.settings.viscosity_exponent",
]
preset_subdir = "fluid"
@@ -477,7 +477,7 @@ class AddPresetNodeColor(AddPresetBase, Operator):
class AddPresetInterfaceTheme(AddPresetBase, Operator):
"""Add a theme preset"""
bl_idname = "wm.interface_theme_preset_add"
bl_label = "Add Tracking Settings Preset"
bl_label = "Add Theme Preset"
preset_menu = "USERPREF_MT_interface_theme_presets"
preset_subdir = "interface_theme"

View File

@@ -0,0 +1,251 @@
# ##### 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-80 compliant>
import bpy
from bpy.types import Operator
from bpy.props import IntProperty
from bpy.props import EnumProperty
class CopyRigidbodySettings(Operator):
'''Copy Rigid Body settings from active object to selected'''
bl_idname = "rigidbody.object_settings_copy"
bl_label = "Copy Rigidbody Settings"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
obj = context.object
return (obj and obj.rigid_body)
def execute(self, context):
obj = context.object
scn = context.scene
# deselect all but mesh objects
for o in context.selected_objects:
if o.type != 'MESH':
o.select = False
sel = context.selected_objects
if sel:
# add selected objects to active one groups and recalculate
bpy.ops.group.objects_add_active()
scn.frame_set(scn.frame_current)
# copy settings
for o in sel:
if o.rigid_body is None:
continue
o.rigid_body.type = obj.rigid_body.type
o.rigid_body.kinematic = obj.rigid_body.kinematic
o.rigid_body.mass = obj.rigid_body.mass
o.rigid_body.collision_shape = obj.rigid_body.collision_shape
o.rigid_body.use_margin = obj.rigid_body.use_margin
o.rigid_body.collision_margin = obj.rigid_body.collision_margin
o.rigid_body.friction = obj.rigid_body.friction
o.rigid_body.restitution = obj.rigid_body.restitution
o.rigid_body.use_deactivation = obj.rigid_body.use_deactivation
o.rigid_body.start_deactivated = obj.rigid_body.start_deactivated
o.rigid_body.deactivate_linear_velocity = obj.rigid_body.deactivate_linear_velocity
o.rigid_body.deactivate_angular_velocity = obj.rigid_body.deactivate_angular_velocity
o.rigid_body.linear_damping = obj.rigid_body.linear_damping
o.rigid_body.angular_damping = obj.rigid_body.angular_damping
o.rigid_body.collision_groups = obj.rigid_body.collision_groups
return {'FINISHED'}
class BakeToKeyframes(Operator):
'''Bake rigid body transformations of selected objects to keyframes'''
bl_idname = "rigidbody.bake_to_keyframes"
bl_label = "Bake To Keyframes"
bl_options = {'REGISTER', 'UNDO'}
frame_start = IntProperty(
name="Start Frame",
description="Start frame for baking",
min=0, max=300000,
default=1,
)
frame_end = IntProperty(
name="End Frame",
description="End frame for baking",
min=1, max=300000,
default=250,
)
step = IntProperty(
name="Frame Step",
description="Frame Step",
min=1, max=120,
default=1,
)
@classmethod
def poll(cls, context):
obj = context.object
return (obj and obj.rigid_body)
def execute(self, context):
bake = []
objs = []
scene = context.scene
frame_orig = scene.frame_current
frames = list(range(self.frame_start, self.frame_end + 1, self.step))
# filter objects selection
for obj in context.selected_objects:
if not obj.rigid_body or obj.rigid_body.type != 'ACTIVE':
obj.select = False
objs = context.selected_objects
if objs:
# store transformation data
for f in list(range(self.frame_start, self.frame_end + 1)):
scene.frame_set(f)
if f in frames:
mat = {}
for i, obj in enumerate(objs):
mat[i] = obj.matrix_world.copy()
bake.append(mat)
# apply transformations as keyframes
for i, f in enumerate(frames):
scene.frame_set(f)
obj_prev = objs[0]
for j, obj in enumerate(objs):
mat = bake[i][j]
obj.location = mat.to_translation()
rot_mode = obj.rotation_mode
if rot_mode == 'QUATERNION':
obj.rotation_quaternion = mat.to_quaternion()
elif rot_mode == 'AXIS_ANGLE':
# this is a little roundabout but there's no better way right now
aa = mat.to_quaternion().to_axis_angle()
obj.rotation_axis_angle = (aa[1], ) + aa[0][:]
else: # euler
# make sure euler rotation is compatible to previous frame
obj.rotation_euler = mat.to_euler(rot_mode, obj_prev.rotation_euler)
obj_prev = obj
bpy.ops.anim.keyframe_insert(type='BUILTIN_KSI_LocRot', confirm_success=False)
# remove baked objects from simulation
bpy.ops.rigidbody.objects_remove()
# clean up keyframes
for obj in objs:
action = obj.animation_data.action
for fcu in action.fcurves:
keyframe_points = fcu.keyframe_points
i = 1
# remove unneeded keyframes
while i < len(keyframe_points) - 1:
val_prev = keyframe_points[i - 1].co[1]
val_next = keyframe_points[i + 1].co[1]
val = keyframe_points[i].co[1]
if abs(val - val_prev) + abs(val - val_next) < 0.0001:
keyframe_points.remove(keyframe_points[i])
else:
i += 1
# use linear interpolation for better visual results
for keyframe in keyframe_points:
keyframe.interpolation = 'LINEAR'
# return to the frame we started on
scene.frame_set(frame_orig)
return {'FINISHED'}
def invoke(self, context, event):
scene = context.scene
self.frame_start = scene.frame_start
self.frame_end = scene.frame_end
wm = context.window_manager
return wm.invoke_props_dialog(self)
class ConnectRigidBodies(Operator):
'''Connect selected rigid bodies to active'''
bl_idname = "rigidbody.connect"
bl_label = "ConnectRigidBodies"
bl_options = {'REGISTER', 'UNDO'}
con_type = EnumProperty(
name="Type",
description="Type of generated contraint",
items=(('FIXED', "Fixed", "Glues ridig bodies together"),
('POINT', "Point", "Constrains rigid bodies to move aound common pivot point"),
('HINGE', "Hinge", "Restricts rigid body rotation to one axis"),
('SLIDER', "Slider", "Restricts rigid boddy translation to one axis"),
('PISTON', "Piston", "Restricts rigid boddy translation and rotation to one axis"),
('GENERIC', "Generic", "Restricts translation and rotation to specified axes"),
('GENERIC_SPRING', "Generic Spring", "Restricts translation and rotation to specified axes with springs")),
default='FIXED',)
pivot_type = EnumProperty(
name="Location",
description="Constraint pivot location",
items=(('CENTER', "Center", "Pivot location is between the constrained rigid bodies"),
('ACTIVE', "Active", "Pivot location is at the active object position"),
('SELECTED', "Selected", "Pivot location is at the slected object position")),
default='CENTER',)
@classmethod
def poll(cls, context):
obj = context.object
objs = context.selected_objects
return (obj and obj.rigid_body and (len(objs) > 1))
def execute(self, context):
objs = context.selected_objects
obj_act = context.active_object
for obj in objs:
if obj == obj_act:
continue
if self.pivot_type == 'ACTIVE':
loc = obj_act.location
elif self.pivot_type == 'SELECTED':
loc = obj.location
else:
loc = (obj_act.location + obj.location) / 2.0
bpy.ops.object.add(type='EMPTY', view_align=False, enter_editmode=False, location=loc)
bpy.ops.rigidbody.constraint_add()
con = context.active_object.rigid_body_constraint
con.type = self.con_type
con.object1 = obj_act
con.object2 = obj
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)

View File

@@ -26,18 +26,18 @@ from bpy.types import Operator
def extend(obj, operator, EXTEND_MODE):
import bmesh
me = obj.data
# script will fail without UVs
if not me.uv_textures:
me.uv_textures.new()
bm = bmesh.from_edit_mesh(me)
f_act = bm.faces.active
uv_act = bm.loops.layers.uv.active
if f_act is None:
operator.report({'ERROR'}, "No active face")
return
@@ -57,7 +57,7 @@ def extend(obj, operator, EXTEND_MODE):
f.tag = False
# tag the active face True since we begin there
f_act.tag = True
def walk_face(f):
# all faces in this list must be tagged
f.tag = True
@@ -102,7 +102,6 @@ def extend(obj, operator, EXTEND_MODE):
else:
break
def extrapolate_uv(fac,
l_a_outer, l_a_inner,
l_b_outer, l_b_inner):
@@ -112,7 +111,7 @@ def extend(obj, operator, EXTEND_MODE):
def apply_uv(f_prev, l_prev, f_next):
l_a = [None, None, None, None]
l_b = [None, None, None, None]
l_a[0] = l_prev
l_a[1] = l_a[0].link_loop_next
l_a[2] = l_a[1].link_loop_next
@@ -133,7 +132,7 @@ def extend(obj, operator, EXTEND_MODE):
# +-----------+
# copy from this face to the one above.
# get the other loops
# get the other loops
l_next = l_prev.link_loop_radial_next
if l_next.vert != l_prev.vert:
l_b[1] = l_next

View File

@@ -189,14 +189,14 @@ class prettyface(object):
def lightmap_uvpack(meshes,
PREF_SEL_ONLY=True,
PREF_NEW_UVLAYER=False,
PREF_PACK_IN_ONE=False,
PREF_APPLY_IMAGE=False,
PREF_IMG_PX_SIZE=512,
PREF_BOX_DIV=8,
PREF_MARGIN_DIV=512
):
PREF_SEL_ONLY=True,
PREF_NEW_UVLAYER=False,
PREF_PACK_IN_ONE=False,
PREF_APPLY_IMAGE=False,
PREF_IMG_PX_SIZE=512,
PREF_BOX_DIV=8,
PREF_MARGIN_DIV=512
):
"""
BOX_DIV if the maximum division of the UV map that
a box may be consolidated into.
@@ -516,7 +516,7 @@ def lightmap_uvpack(meshes,
def unwrap(operator, context, **kwargs):
is_editmode = (bpy.context.object.mode == 'EDIT')
is_editmode = (context.object.mode == 'EDIT')
if is_editmode:
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)

View File

@@ -500,18 +500,16 @@ class WM_MT_context_menu_enum(Menu):
def draw(self, context):
data_path = self.data_path
value = context_path_validate(bpy.context, data_path)
value = context_path_validate(context, data_path)
if value is Ellipsis:
return {'PASS_THROUGH'}
base_path, prop_string = data_path.rsplit(".", 1)
value_base = context_path_validate(context, base_path)
prop = value_base.bl_rna.properties[prop_string]
values = [(i.name, i.identifier) for i in value_base.bl_rna.properties[prop_string].enum_items]
for name, identifier in values:
props = self.layout.operator("wm.context_set_enum", text=name)
props.data_path = data_path
props.value = identifier
layout = self.layout
layout.label(prop.name, icon=prop.icon)
layout.prop(value_base, prop_string, expand=True)
class WM_OT_context_menu_enum(Operator):
@@ -1255,13 +1253,6 @@ class WM_OT_copy_prev_settings(Operator):
else:
shutil.copytree(path_src, path_dst, symlinks=True)
# in 2.57 and earlier windows installers, system scripts were copied
# into the configuration directory, don't want to copy those
system_script = os.path.join(path_dst, "scripts/modules/bpy_types.py")
if os.path.isfile(system_script):
shutil.rmtree(os.path.join(path_dst, "scripts"))
shutil.rmtree(os.path.join(path_dst, "plugins"))
# don't loose users work if they open the splash later.
if bpy.data.is_saved is bpy.data.is_dirty is False:
bpy.ops.wm.read_homefile()
@@ -1596,7 +1587,7 @@ class WM_OT_addon_enable(Operator):
"version %d.%d.%d and might not "
"function (correctly), "
"though it is enabled") %
info_ver)
info_ver)
return {'FINISHED'}
else:
return {'CANCELLED'}
@@ -1739,7 +1730,7 @@ class WM_OT_addon_install(Operator):
# don't use bpy.utils.script_paths("addons") because we may not be able to write to it.
path_addons = bpy.utils.user_resource('SCRIPTS', "addons", create=True)
else:
path_addons = bpy.context.user_preferences.filepaths.script_directory
path_addons = context.user_preferences.filepaths.script_directory
if path_addons:
path_addons = os.path.join(path_addons, "addons")