This commit is contained in:
Brecht Van Lommel
2011-05-05 10:14:56 +00:00
211 changed files with 5443 additions and 3029 deletions

View File

@@ -33,6 +33,7 @@ import sys as _sys
import addon_utils as _addon_utils
_script_module_dirs = "startup", "modules"
def _test_import(module_name, loaded_modules):
use_time = _bpy.app.debug
@@ -183,7 +184,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
_global_loaded_modules[:] = []
for base_path in script_paths():
for path_subdir in ("startup", "modules"):
for path_subdir in _script_module_dirs:
path = _os.path.join(base_path, path_subdir)
if _os.path.isdir(path):
_sys_path_ensure(path)
@@ -226,27 +227,41 @@ def user_script_path():
return None
def script_paths(subdir=None, user=True):
def script_paths(subdir=None, user_pref=True, all=False):
"""
Returns a list of valid script paths from the home directory and user preferences.
Returns a list of valid script paths.
Accepts any number of string arguments which are joined to make a path.
:arg subdir: Optional subdir.
:type subdir: string
:arg user_pref: Include the user preference script path.
:type user_pref: bool
:arg all: Include local, user and system paths rather just the paths blender uses.
:type all: bool
:return: script paths.
:rtype: list
"""
scripts = list(_scripts)
# add user scripts dir
if user:
if user_pref:
user_script_path = _bpy.context.user_preferences.filepaths.script_directory
else:
user_script_path = None
for path in _bpy_script_paths() + (user_script_path, ):
if all:
# all possible paths
base_paths = tuple(_os.path.join(resource_path(res), "scripts") for res in ('LOCAL', 'USER', 'SYSTEM'))
else:
# only paths blender uses
base_paths = _bpy_script_paths()
for path in base_paths + (user_script_path, ):
if path:
path = _os.path.normpath(path)
if path not in scripts and _os.path.isdir(path):
scripts.append(path)
if not subdir:
if subdir is None:
return scripts
script_paths = []
@@ -258,6 +273,24 @@ def script_paths(subdir=None, user=True):
return script_paths
def refresh_script_paths():
"""
Run this after creating new script paths to update sys.path
"""
for base_path in script_paths():
for path_subdir in _script_module_dirs:
path = _os.path.join(base_path, path_subdir)
if _os.path.isdir(path):
_sys_path_ensure(path)
for path in _addon_utils.paths():
_sys_path_ensure(path)
path = _os.path.join(path, "modules")
if _os.path.isdir(path):
_sys_path_ensure(path)
_presets = _os.path.join(_scripts[0], "presets") # FIXME - multiple paths
@@ -266,7 +299,7 @@ def preset_paths(subdir):
Returns a list of paths for a specific preset.
"""
dirs = []
for path in script_paths("presets"):
for path in script_paths("presets", all=True):
directory = _os.path.join(path, subdir)
if _os.path.isdir(directory):
dirs.append(directory)

View File

@@ -10,4 +10,4 @@ bpy.context.user_preferences.inputs.select_mouse = 'RIGHT'
bpy.context.user_preferences.inputs.view_zoom_method = 'DOLLY'
bpy.context.user_preferences.inputs.view_zoom_axis = 'VERTICAL'
bpy.context.user_preferences.inputs.view_rotate_method = 'TRACKBALL'
bpy.context.user_preferences.inputs.invert_mouse_wheel_zoom = False
bpy.context.user_preferences.inputs.invert_mouse_zoom = False

View File

@@ -7,4 +7,4 @@ bpy.context.user_preferences.inputs.select_mouse = 'LEFT'
bpy.context.user_preferences.inputs.view_zoom_method = 'DOLLY'
bpy.context.user_preferences.inputs.view_zoom_axis = 'HORIZONTAL'
bpy.context.user_preferences.inputs.view_rotate_method = 'TURNTABLE'
bpy.context.user_preferences.inputs.invert_mouse_wheel_zoom = True
bpy.context.user_preferences.inputs.invert_mouse_zoom = True

View File

@@ -20,6 +20,8 @@
import bpy
from bpy.props import EnumProperty
class MeshSelectInteriorFaces(bpy.types.Operator):
'''Select faces where all edges have more then 2 face users.'''
@@ -66,17 +68,23 @@ class MeshSelectInteriorFaces(bpy.types.Operator):
class MeshMirrorUV(bpy.types.Operator):
'''Copy mirror UV coordinates on the X axis based on a mirrored mesh'''
bl_idname = "mesh.faces_miror_uv"
bl_idname = "mesh.faces_mirror_uv"
bl_label = "Copy Mirrored UV coords"
bl_options = {'REGISTER', 'UNDO'}
direction = EnumProperty(items=(
('POSITIVE', "Positive", ""),
('NEGATIVE', "Negative", "")),
name="Axis Direction",
description="")
@classmethod
def poll(cls, context):
ob = context.active_object
return (ob and ob.type == 'MESH')
def execute(self, context):
DIR = 1 # TODO, make an option
DIR = (self.direction == 'NEGATIVE')
from mathutils import Vector

View File

@@ -48,11 +48,11 @@ class AddPresetBase():
preset_menu_class = getattr(bpy.types, self.preset_menu)
if not self.remove_active:
if not self.name:
name = self.name.strip()
if not name:
return {'FINISHED'}
filename = self.as_filename(self.name)
filename = self.as_filename(name)
target_path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", self.preset_subdir), create=True)
@@ -118,7 +118,7 @@ class AddPresetBase():
return {'FINISHED'}
def check(self, context):
self.name = self.as_filename(self.name)
self.name = self.as_filename(self.name.strip())
def invoke(self, context, event):
if not self.remove_active:
@@ -264,7 +264,7 @@ class AddPresetInteraction(AddPresetBase, bpy.types.Operator):
preset_values = [
"user_preferences.edit.use_drag_immediately",
"user_preferences.edit.use_insertkey_xyz_to_rgb",
"user_preferences.inputs.invert_mouse_wheel_zoom",
"user_preferences.inputs.invert_mouse_zoom",
"user_preferences.inputs.select_mouse",
"user_preferences.inputs.use_emulate_numpad",
"user_preferences.inputs.use_mouse_continuous",
@@ -327,7 +327,7 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
ret = []
for prop_id, prop in operator_rna.properties.items():
if (not prop.is_hidden) and prop_id not in properties_blacklist:
ret.append("op.%s" % prop_id)
ret.append("op.%s" % prop_id)
return ret

View File

@@ -395,7 +395,7 @@ class WM_MT_context_menu_enum(bpy.types.Menu):
base_path, prop_string = data_path.rsplit(".", 1)
value_base = context_path_validate(context, base_path)
values = [(i.name, i.identifier) for i in value_base.bl_rna.properties[prop_string].items]
values = [(i.name, i.identifier) for i in value_base.bl_rna.properties[prop_string].enum_items]
for name, identifier in values:
prop = self.layout.operator("wm.context_set_enum", text=name)
@@ -837,6 +837,7 @@ class WM_OT_properties_add(bpy.types.Operator):
item[property] = 1.0
return {'FINISHED'}
class WM_OT_properties_context_change(bpy.types.Operator):
"Change the context tab in a Properties Window"
bl_idname = "wm.properties_context_change"
@@ -846,7 +847,6 @@ class WM_OT_properties_context_change(bpy.types.Operator):
def execute(self, context):
context.space_data.context = (self.context)
return {'FINISHED'}

View File

@@ -581,7 +581,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
col.prop(md, "use_even_offset")
col.prop(md, "use_quality_normals")
col.prop(md, "use_rim")
sub = col.column()
sub.label()
row = sub.split(align=True, percentage=0.4)
@@ -635,6 +635,48 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
sub.prop(md, "scale_x", text="Scale X")
sub.prop(md, "scale_y", text="Scale Y")
def WARP(self, layout, ob, md):
use_falloff = (md.falloff_type != 'NONE')
split = layout.split()
col = split.column()
col.label(text="From:")
col.prop(md, "object_from", text="")
col.prop(md, "use_volume_preserve")
col = split.column()
col.label(text="To:")
col.prop(md, "object_to", text="")
col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
col = layout.column()
row = col.row(align=True)
row.prop(md, "strength")
if use_falloff:
row.prop(md, "falloff_radius")
col.prop(md, "falloff_type")
if use_falloff:
if md.falloff_type == 'CURVE':
col.template_curve_mapping(md, "falloff_curve")
# 2 new columns
split = layout.split()
col = split.column()
col.label(text="Texture:")
col.prop(md, "texture", text="")
col = split.column()
col.label(text="Texture Coordinates:")
col.prop(md, "texture_coords", text="")
if md.texture_coords == 'OBJECT':
layout.prop(md, "texture_coordinate_object", text="Object")
elif md.texture_coords == 'UV' and ob.type == 'MESH':
layout.prop_object(md, "uv_layer", ob.data, "uv_textures")
def WAVE(self, layout, ob, md):
split = layout.split()

View File

@@ -323,6 +323,7 @@ class RENDER_PT_game_shading(RenderButtonsPanel, bpy.types.Panel):
col.prop(gs, "use_glsl_lights", text="Lights")
col.prop(gs, "use_glsl_shaders", text="Shaders")
col.prop(gs, "use_glsl_shadows", text="Shadows")
col.prop(gs, "use_glsl_color_management", text="Color Management")
col = split.column()
col.prop(gs, "use_glsl_ramps", text="Ramps")

View File

@@ -549,6 +549,7 @@ class MATERIAL_PT_halo(MaterialButtonsPanel, bpy.types.Panel):
col = split.column()
col.prop(mat, "alpha")
col.prop(mat, "diffuse_color", text="")
col.prop(halo, "seed")
col = split.column()
col.prop(halo, "size")

View File

@@ -157,6 +157,8 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, bpy.types.Panel):
col = split.column()
col.prop(cloth, "collision_quality", slider=True, text="Quality")
col.prop(cloth, "distance_min", slider=True, text="Distance")
col.prop(cloth, "repel_force", slider=True, text="Repel")
col.prop(cloth, "distance_repel", slider=True, text="Repel Distance")
col.prop(cloth, "friction")
col = split.column()

View File

@@ -721,6 +721,15 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, bpy.types.Panel):
col.prop(pd, "falloff", text="")
if pd.falloff == 'SOFT':
col.prop(pd, "falloff_soft")
if pd.falloff == "PARTICLE_VELOCITY":
col.prop(pd, "falloff_speed_scale")
col.prop(pd, "use_falloff_curve")
if pd.use_falloff_curve:
col = layout.column()
col.label(text="Falloff Curve")
col.template_curve_mapping(pd, "falloff_curve", brush=False)
class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, bpy.types.Panel):

View File

@@ -91,7 +91,7 @@ class IMAGE_MT_select(bpy.types.Menu):
layout.separator()
layout.operator("uv.select_all")
layout.operator("uv.select_inverse")
layout.operator("uv.select_all", text="Inverse").action = 'INVERT'
layout.operator("uv.unlink_selected")
layout.separator()
@@ -263,7 +263,7 @@ class IMAGE_MT_uvs(bpy.types.Menu):
layout.operator("uv.average_islands_scale")
layout.operator("uv.minimize_stretch")
layout.operator("uv.stitch")
layout.operator("mesh.faces_miror_uv")
layout.operator("mesh.faces_mirror_uv")
layout.separator()
@@ -370,10 +370,7 @@ class IMAGE_HT_header(bpy.types.Header):
layout.prop(toolsettings, "use_uv_select_sync", text="")
if toolsettings.use_uv_select_sync:
row = layout.row(align=True)
row.prop(toolsettings, "mesh_select_mode", text="", index=0, icon='VERTEXSEL')
row.prop(toolsettings, "mesh_select_mode", text="", index=1, icon='EDGESEL')
row.prop(toolsettings, "mesh_select_mode", text="", index=2, icon='FACESEL')
layout.template_edit_mode_selection()
else:
layout.prop(toolsettings, "uv_select_mode", text="", expand=True)
layout.prop(uvedit, "sticky_select_mode", text="", icon_only=True)

View File

@@ -1103,7 +1103,8 @@ class WM_OT_addon_install(bpy.types.Operator):
del pyfile_dir
# done checking for exceptional case
contents = set(os.listdir(path_addons))
addon_files_old = set(os.listdir(path_addons))
addons_old = {mod.__name__ for mod in addon_utils.modules(USERPREF_PT_addons._addons_fake_modules)}
#check to see if the file is in compressed format (.zip)
if zipfile.is_zipfile(pyfile):
@@ -1152,11 +1153,13 @@ class WM_OT_addon_install(bpy.types.Operator):
traceback.print_exc()
return {'CANCELLED'}
addons_new = {mod.__name__ for mod in addon_utils.modules(USERPREF_PT_addons._addons_fake_modules)} - addons_old
addons_new.discard("modules")
# disable any addons we may have enabled previously and removed.
# this is unlikely but do just incase. bug [#23978]
addons_new = set(os.listdir(path_addons)) - contents
for new_addon in addons_new:
addon_utils.disable(os.path.splitext(new_addon)[0])
addon_utils.disable(new_addon)
# possible the zip contains multiple addons, we could disallow this
# but for now just use the first
@@ -1169,6 +1172,9 @@ class WM_OT_addon_install(bpy.types.Operator):
context.window_manager.addon_search = info["name"]
break
# incase a new module path was created to install this addon.
bpy.utils.refresh_script_paths()
# TODO, should not be a warning.
# self.report({'WARNING'}, "File installed to '%s'\n" % path_dest)
return {'FINISHED'}

View File

@@ -555,13 +555,7 @@ class WM_OT_keyconfig_import(bpy.types.Operator):
config_name = basename(self.filepath)
path = bpy.utils.preset_paths("keyconfig")[0] # we need some way to tell the user and system preset path
print(path)
# create config folder if needed
if not os.path.exists(path):
os.mkdir(path)
path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
path = os.path.join(path, config_name)
if self.keep_original:

View File

@@ -851,10 +851,15 @@ class VIEW3D_MT_object_apply(bpy.types.Menu):
def draw(self, context):
layout = self.layout
layout.operator("object.location_apply", text="Location")
layout.operator("object.rotation_apply", text="Rotation")
layout.operator("object.scale_apply", text="Scale")
layout.operator("object.transform_apply", text="Location").location = True
layout.operator("object.transform_apply", text="Rotation").rotation = True
layout.operator("object.transform_apply", text="Scale").scale = True
props = layout.operator("object.transform_apply", text="Rotation & Scale")
props.scale = True
props.rotation = True
layout.separator()
layout.operator("object.visual_transform_apply", text="Visual Transform")
layout.operator("object.duplicates_make_real")

View File

@@ -946,26 +946,21 @@ class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
sculpt = tool_settings.sculpt
settings = __class__.paint_settings(context)
split = layout.split()
col = split.column()
col.prop(sculpt, "use_threaded", text="Threaded Sculpt")
col.prop(sculpt, "show_low_resolution")
col.prop(sculpt, "show_brush")
col.label(text="Unified Settings:")
col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
col = split.column()
col.label(text="Lock:")
row = col.row(align=True)
layout.label(text="Lock:")
row = layout.row(align=True)
row.prop(sculpt, "lock_x", text="X", toggle=True)
row.prop(sculpt, "lock_y", text="Y", toggle=True)
row.prop(sculpt, "lock_z", text="Z", toggle=True)
layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
layout.prop(sculpt, "show_low_resolution")
layout.prop(sculpt, "show_brush")
layout.prop(sculpt, "use_deform_only")
layout.label(text="Unified Settings:")
layout.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
layout.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
bl_label = "Symmetry"

View File

@@ -17,7 +17,7 @@ from bpy.props import StringProperty, BoolProperty, EnumProperty
class ExportSomeData(bpy.types.Operator, ExportHelper):
'''This appiers in the tooltip of the operator and in the generated docs.'''
'''This appears in the tooltip of the operator and in the generated docs.'''
bl_idname = "export.some_data" # this is important since its how bpy.ops.export.some_data is constructed
bl_label = "Export Some Data"