Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2011-07-05 17:54:25 +0400
committerJoerg Mueller <nexyon@gmail.com>2011-07-05 17:54:25 +0400
commit3f3c6f5f1fb336f8f0015d7857a1ae153fa2a80f (patch)
tree27e2ae66dd589013c24592fe0803b440a7e014be /release/scripts
parent887fd19894047832fbb7a7300e5fc11438b1f3b2 (diff)
parentccd31900ab9659b6fdc035fd91bff9f508334e22 (diff)
Merging from trunk up to r38119.
Diffstat (limited to 'release/scripts')
-rw-r--r--release/scripts/modules/bpy/__init__.py29
-rw-r--r--release/scripts/modules/bpy_extras/mesh_utils.py6
-rw-r--r--release/scripts/modules/console/intellisense.py15
-rw-r--r--release/scripts/startup/bl_operators/image.py2
-rw-r--r--release/scripts/startup/bl_operators/mesh.py11
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py2
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py64
-rw-r--r--release/scripts/startup/bl_operators/wm.py71
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py9
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py1
-rw-r--r--release/scripts/startup/bl_ui/space_image.py3
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py80
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py78
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py10
16 files changed, 306 insertions, 83 deletions
diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py
index 1df8e9e5588..9c48dc89f83 100644
--- a/release/scripts/modules/bpy/__init__.py
+++ b/release/scripts/modules/bpy/__init__.py
@@ -22,24 +22,29 @@
Give access to blender data and utility functions.
"""
-# internal blender C module
-import _bpy
-from _bpy import types, props, app
+__all__ = (
+ "app",
+ "context",
+ "data",
+ "ops",
+ "path",
+ "props",
+ "types",
+ "utils",
+)
+
-data = _bpy.data
-context = _bpy.context
+# internal blender C module
+from _bpy import types, props, app, data, context
# python modules
-from . import utils, path
-from . import ops as _ops_module
+from . import utils, path, ops
# fake operator module
-ops = _ops_module.ops_fake_module
-
-import sys as _sys
-
+ops = ops.ops_fake_module
def _main():
+ import sys as _sys
# Possibly temp. addons path
from os.path import join, dirname, normpath
@@ -59,3 +64,5 @@ def _main():
_main()
+
+del _main
diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py
index 2062fe4485f..8ed50972c54 100644
--- a/release/scripts/modules/bpy_extras/mesh_utils.py
+++ b/release/scripts/modules/bpy_extras/mesh_utils.py
@@ -105,9 +105,9 @@ def edge_face_count(mesh):
:return: list face users for each item in mesh.edges.
:rtype: list
"""
- edge_face_count_dict = edge_face_count_dict(mesh)
+ edge_face_count = edge_face_count_dict(mesh)
get = dict.get
- return [get(edge_face_count_dict, ed.key, 0) for ed in mesh.edges]
+ return [get(edge_face_count, ed.key, 0) for ed in mesh.edges]
def edge_loops_from_faces(mesh, faces=None, seams=()):
@@ -287,7 +287,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
else:
return v1[1], v2[1]
- if not PREF_FIX_LOOPS:
+ if not fix_loops:
'''
Normal single concave loop filling
'''
diff --git a/release/scripts/modules/console/intellisense.py b/release/scripts/modules/console/intellisense.py
index 072d467ff86..a177b305fda 100644
--- a/release/scripts/modules/console/intellisense.py
+++ b/release/scripts/modules/console/intellisense.py
@@ -53,7 +53,7 @@ RE_UNQUOTED_WORD = re.compile(
re.UNICODE)
-def complete(line, cursor, namespace, private=True):
+def complete(line, cursor, namespace, private):
"""Returns a list of possible completions:
* name completion
@@ -82,6 +82,9 @@ def complete(line, cursor, namespace, private=True):
if RE_MODULE.match(line):
from . import complete_import
matches = complete_import.complete(line)
+ if not private:
+ matches[:] = [m for m in matches if m[:1] != "_"]
+ matches.sort()
else:
from . import complete_namespace
matches = complete_namespace.complete(word, namespace, private)
@@ -130,11 +133,15 @@ def expand(line, cursor, namespace, private=True):
else:
# causes blender bug [#27495] since string keys may contain '.'
# scrollback = ' '.join([m.split('.')[-1] for m in matches])
+
+ # add white space to align with the cursor
+ white_space = " " + (" " * (cursor + len(prefix)))
word_prefix = word + prefix
- scrollback = ' '.join(
- [m[len(word_prefix):]
+ scrollback = '\n'.join(
+ [white_space + m[len(word_prefix):]
if (word_prefix and m.startswith(word_prefix))
- else m.split('.')[-1]
+ else
+ white_space + m.split('.')[-1]
for m in matches])
no_calltip = True
diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py
index 462db3a2c5e..1e5217217dd 100644
--- a/release/scripts/startup/bl_operators/image.py
+++ b/release/scripts/startup/bl_operators/image.py
@@ -60,7 +60,7 @@ class EditExternally(bpy.types.Operator):
filepath = bpy.path.abspath(self.filepath)
if not os.path.exists(filepath):
- self.report({'ERROR'}, "Image path %r not found." % filepath)
+ self.report({'ERROR'}, "Image path %r not found, image may be packed or unsaved." % filepath)
return {'CANCELLED'}
cmd = self._editor_guess(context) + [filepath]
diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py
index 996b38ae571..8dca30e54df 100644
--- a/release/scripts/startup/bl_operators/mesh.py
+++ b/release/scripts/startup/bl_operators/mesh.py
@@ -81,8 +81,8 @@ class MeshMirrorUV(bpy.types.Operator):
@classmethod
def poll(cls, context):
- ob = context.active_object
- return (ob and ob.type == 'MESH')
+ obj = context.active_object
+ return (obj and obj.type == 'MESH' and obj.data.uv_textures.active)
def execute(self, context):
DIR = (self.direction == 'NEGATIVE')
@@ -120,12 +120,7 @@ class MeshMirrorUV(bpy.types.Operator):
if j is not None:
vmap[i] = j
- active_uv_layer = None
- for lay in mesh.uv_textures:
- if lay.active:
- active_uv_layer = lay.data
- break
-
+ active_uv_layer = mesh.uv_textures.active.data
fuvs = [(uv.uv1, uv.uv2, uv.uv3, uv.uv4) for uv in active_uv_layer]
fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy()) for uv in fuvs]
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index a8bb3227b3c..074f204d50e 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -132,7 +132,7 @@ class QuickExplode(bpy.types.Operator):
fake_context = bpy.context.copy()
obj_act = context.active_object
- if obj_act.type != 'MESH':
+ if obj_act is None or obj_act.type != 'MESH':
self.report({'ERROR'}, "Active object is not a mesh")
return {'CANCELLED'}
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index c70b9071985..7ea89cfa479 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -746,13 +746,15 @@ def packIslands(islandList):
uv.y= (uv.y+yoffset) * yfactor
-
def VectoQuat(vec):
- vec = vec.normalized()
- if abs(vec.x) > 0.5:
- return vec.to_track_quat('Z', 'X')
- else:
- return vec.to_track_quat('Z', 'Y')
+ a3 = vec.normalized()
+ up = Vector((0.0, 0.0, 1.0))
+ if abs(a3.dot(up)) == 1.0:
+ up = Vector((0.0, 1.0, 0.0))
+
+ a1 = a3.cross(up).normalized()
+ a2 = a3.cross(a1)
+ return Matrix((a1, a2, a3)).to_quaternion()
class thickface(object):
@@ -791,7 +793,11 @@ def main_consts():
global ob
ob = None
-def main(context, island_margin, projection_limit):
+def main(context,
+ island_margin,
+ projection_limit,
+ user_area_weight,
+ ):
global USER_FILL_HOLES
global USER_FILL_HOLES_QUALITY
global USER_STRETCH_ASPECT
@@ -812,21 +818,25 @@ def main(context, island_margin, projection_limit):
global RotMatStepRotation
main_consts()
-#XXX objects= bpy.data.scenes.active.objects
- objects = context.selected_editable_objects
-
+ # TODO, all selected meshes
+ '''
+ # objects = context.selected_editable_objects
+ objects = []
# we can will tag them later.
obList = [ob for ob in objects if ob.type == 'MESH']
# Face select object may not be selected.
-#XXX ob = objects.active
- ob= objects[0]
+ ob = context.active_object
if ob and (not ob.select) and ob.type == 'MESH':
# Add to the list
obList =[ob]
del objects
+ '''
+
+ # quick workaround
+ obList = [ob for ob in [context.active_object] if ob and ob.type == 'MESH']
if not obList:
raise('error, no selected mesh objects')
@@ -840,7 +850,6 @@ def main(context, island_margin, projection_limit):
USER_FILL_HOLES = (0)
USER_FILL_HOLES_QUALITY = (50) # Only for hole filling.
USER_VIEW_INIT = (0) # Only for hole filling.
- USER_AREA_WEIGHT = (1) # Only for hole filling.
# Reuse variable
if len(obList) == 1:
@@ -966,12 +975,15 @@ def main(context, island_margin, projection_limit):
# Add the average of all these faces normals as a projectionVec
averageVec = Vector((0.0, 0.0, 0.0))
- if USER_AREA_WEIGHT:
+ if user_area_weight == 0.0:
for fprop in newProjectMeshFaces:
- averageVec += (fprop.no * fprop.area)
+ averageVec += fprop.no
+ elif user_area_weight == 1.0:
+ for fprop in newProjectMeshFaces:
+ averageVec += fprop.no * fprop.area
else:
for fprop in newProjectMeshFaces:
- averageVec += fprop.no
+ averageVec += fprop.no * ((fprop.area * user_area_weight) + (1.0 - user_area_weight))
if averageVec.x != 0 or averageVec.y != 0 or averageVec.z != 0: # Avoid NAN
projectVecs.append(averageVec.normalized())
@@ -1058,7 +1070,7 @@ def main(context, island_margin, projection_limit):
f_uv = f.uv
for j, v in enumerate(f.v):
# XXX - note, between mathutils in 2.4 and 2.5 the order changed.
- f_uv[j][:] = (v.co * MatQuat)[:2]
+ f_uv[j][:] = (v.co * MatQuat).xy
if USER_SHARE_SPACE:
@@ -1094,12 +1106,8 @@ def main(context, island_margin, projection_limit):
"""
pup_block = [\
'Projection',\
-* ('Angle Limit:', USER_PROJECTION_LIMIT, 1, 89, ''),\
('Selected Faces Only', USER_ONLY_SELECTED_FACES, 'Use only selected faces from all selected meshes.'),\
('Init from view', USER_VIEW_INIT, 'The first projection will be from the view vector.'),\
- ('Area Weight', USER_AREA_WEIGHT, 'Weight projections vector by face area.'),\
- '',\
- '',\
'',\
'UV Layout',\
('Share Tex Space', USER_SHARE_SPACE, 'Objects Share texture space, map all objects into 1 uvmap.'),\
@@ -1121,11 +1129,15 @@ class SmartProject(bpy.types.Operator):
bl_options = {'REGISTER', 'UNDO'}
angle_limit = FloatProperty(name="Angle Limit",
- description="lower for more projection groups, higher for less distortion.",
+ description="lower for more projection groups, higher for less distortion",
default=66.0, min=1.0, max=89.0)
island_margin = FloatProperty(name="Island Margin",
- description="Margin to reduce bleed from adjacent islands.",
+ description="Margin to reduce bleed from adjacent islands",
+ default=0.0, min=0.0, max=1.0)
+
+ user_area_weight = FloatProperty(name="Area Weight",
+ description="Weight projections vector by faces with larger areas",
default=0.0, min=0.0, max=1.0)
@classmethod
@@ -1133,7 +1145,11 @@ class SmartProject(bpy.types.Operator):
return context.active_object != None
def execute(self, context):
- main(context, self.island_margin, self.angle_limit)
+ main(context,
+ self.island_margin,
+ self.angle_limit,
+ self.user_area_weight,
+ )
return {'FINISHED'}
def invoke(self, context, event):
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index fcc30ecbb4b..af33e45668c 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -19,7 +19,9 @@
# <pep8 compliant>
import bpy
-from bpy.props import StringProperty, BoolProperty, IntProperty, FloatProperty
+from bpy.props import StringProperty, BoolProperty, IntProperty, \
+ FloatProperty, EnumProperty
+
from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear
@@ -457,15 +459,76 @@ doc_id = StringProperty(name="Doc ID",
doc_new = StringProperty(name="Edit Description",
description="", maxlen=1024, default="")
+data_path_iter = StringProperty(
+ description="The data path relative to the context, must point to an iterable.")
+
+data_path_item = StringProperty(
+ description="The data path from each iterable to the value (int or float)")
+
+
+class WM_OT_context_collection_boolean_set(bpy.types.Operator):
+ '''Set boolean values for a collection of items'''
+ bl_idname = "wm.context_collection_boolean_set"
+ bl_label = "Context Collection Boolean Set"
+ bl_options = {'UNDO', 'REGISTER', 'INTERNAL'}
+
+ data_path_iter = data_path_iter
+ data_path_item = data_path_item
+
+ type = EnumProperty(items=(
+ ('TOGGLE', "Toggle", ""),
+ ('ENABLE', "Enable", ""),
+ ('DISABLE', "Disable", ""),
+ ),
+ name="Type")
+
+ def execute(self, context):
+ data_path_iter = self.data_path_iter
+ data_path_item = self.data_path_item
+
+ items = list(getattr(context, data_path_iter))
+ items_ok = []
+ is_set = False
+ for item in items:
+ try:
+ value_orig = eval("item." + data_path_item)
+ except:
+ continue
+
+ if value_orig == True:
+ is_set = True
+ elif value_orig == False:
+ pass
+ else:
+ self.report({'WARNING'}, "Non boolean value found: %s[ ].%s" %
+ (data_path_iter, data_path_item))
+ return {'CANCELLED'}
+
+ items_ok.append(item)
+
+ if self.type == 'ENABLE':
+ is_set = True
+ elif self.type == 'DISABLE':
+ is_set = False
+ else:
+ is_set = not is_set
+
+ exec_str = "item.%s = %s" % (data_path_item, is_set)
+ for item in items_ok:
+ exec(exec_str)
+
+ return {'FINISHED'}
+
class WM_OT_context_modal_mouse(bpy.types.Operator):
'''Adjust arbitrary values with mouse input'''
bl_idname = "wm.context_modal_mouse"
bl_label = "Context Modal Mouse"
- bl_options = {'INTERNAL'}
+ bl_options = {'GRAB_POINTER', 'BLOCKING', 'INTERNAL'}
+
+ data_path_iter = data_path_iter
+ data_path_item = data_path_item
- data_path_iter = StringProperty(description="The data path relative to the context, must point to an iterable.")
- data_path_item = StringProperty(description="The data path from each iterable to the value (int or float)")
input_scale = FloatProperty(default=0.01, description="Scale the mouse movement by this value before applying the delta")
invert = BoolProperty(default=False, description="Invert the mouse input")
initial_x = IntProperty(options={'HIDDEN'})
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 8c966825aee..618a88f0879 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -290,9 +290,8 @@ class DATA_PT_texface(MeshButtonsPanel, bpy.types.Panel):
@classmethod
def poll(cls, context):
- ob = context.active_object
-
- return (context.mode == 'EDIT_MESH') and ob and ob.type == 'MESH'
+ obj = context.object
+ return (context.mode == 'EDIT_MESH') and obj and obj.type == 'MESH'
def draw(self, context):
layout = self.layout
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 52d6b5f1376..45c15bd1ce6 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -729,6 +729,7 @@ class MATERIAL_PT_options(MaterialButtonsPanel, bpy.types.Panel):
col.prop(mat, "use_vertex_color_paint")
col.prop(mat, "use_vertex_color_light")
col.prop(mat, "use_object_color")
+ col.prop(mat, "pass_index")
class MATERIAL_PT_shadow(MaterialButtonsPanel, bpy.types.Panel):
@@ -883,7 +884,7 @@ class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, bpy.types.Panel):
sub = col.column()
sub.enabled = True
sub.active = False
- sub.prop(vol, "use_light_cache")
+ sub.label("Light Cache Enabled")
col.prop(vol, "cache_resolution")
sub = col.column(align=True)
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 63333083cb2..4c92296dacd 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -879,6 +879,15 @@ class PARTICLE_PT_render(ParticleButtonsPanel, bpy.types.Panel):
col = row.column()
col.prop(part, "billboard_offset")
+ row = layout.row()
+ col = row.column()
+ col.prop(part, "billboard_size", text="Scale")
+ if part.billboard_align == 'VEL':
+ col = row.column(align=True)
+ col.label("Velocity Scale:")
+ col.prop(part, "billboard_velocity_head", text="Head")
+ col.prop(part, "billboard_velocity_tail", text="Tail")
+
if psys:
col = layout.column()
col.prop_search(psys, "billboard_normal_uv", ob.data, "uv_textures")
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 9ff4470641b..3ba54aa67c6 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -141,6 +141,7 @@ class RENDER_PT_layers(RenderButtonsPanel, bpy.types.Panel):
col.prop(rl, "use_pass_uv")
col.prop(rl, "use_pass_mist")
col.prop(rl, "use_pass_object_index")
+ col.prop(rl, "use_pass_material_index")
col.prop(rl, "use_pass_color")
col = split.column()
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 9f69ca17076..b1322d453fc 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -616,10 +616,9 @@ class IMAGE_PT_view_properties(bpy.types.Panel):
split = layout.split()
col = split.column()
+ col.prop(uvedit, "show_faces")
col.prop(uvedit, "show_smooth_edges", text="Smooth")
col.prop(uvedit, "show_modified_edges", text="Modified")
- #col.prop(uvedit, "show_edges")
- #col.prop(uvedit, "show_faces")
col = split.column()
col.prop(uvedit, "show_stretch", text="Stretch")
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index dd5b8438cb2..0514d7a06d3 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -850,7 +850,7 @@ class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
class USERPREF_MT_addons_dev_guides(bpy.types.Menu):
- bl_label = "Develoment Guides"
+ bl_label = "Development Guides"
# menu to open webpages with addons development guides
def draw(self, context):
@@ -877,6 +877,19 @@ class USERPREF_PT_addons(bpy.types.Panel):
def module_get(mod_name):
return USERPREF_PT_addons._addons_fake_modules[mod_name]
+ @staticmethod
+ def is_user_addon(mod, user_addon_paths):
+ if not user_addon_paths:
+ user_script_path = bpy.utils.user_script_path()
+ if user_script_path is not None:
+ user_addon_paths.append(os.path.join(user_script_path(), "addons"))
+ user_addon_paths.append(os.path.join(bpy.utils.resource_path('USER'), "scripts", "addons"))
+
+ for path in user_addon_paths:
+ if bpy.path.is_subdir(mod.__file__, path):
+ return True
+ return False
+
def draw(self, context):
layout = self.layout
@@ -901,6 +914,9 @@ class USERPREF_PT_addons(bpy.types.Panel):
search = context.window_manager.addon_search.lower()
support = context.window_manager.addon_support
+ # initialized on demand
+ user_addon_paths = []
+
for mod, info in addons:
module_name = mod.__name__
@@ -970,20 +986,24 @@ class USERPREF_PT_addons(bpy.types.Panel):
split = colsub.row().split(percentage=0.15)
split.label(text="Warning:")
split.label(text=' ' + info["warning"], icon='ERROR')
- if info["wiki_url"] or info["tracker_url"]:
+
+ user_addon = __class__.is_user_addon(mod, user_addon_paths)
+ tot_row = bool(info["wiki_url"]) + bool(info["tracker_url"]) + bool(user_addon)
+
+ if tot_row:
split = colsub.row().split(percentage=0.15)
split.label(text="Internet:")
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 user_addon:
+ split.operator("wm.addon_remove", text="Remove", icon='CANCEL').module = mod.__name__
- if info["wiki_url"] and info["tracker_url"]:
- split.separator()
- else:
- split.separator()
+ for i in range(4 - tot_row):
split.separator()
+
# Append missing scripts
# First collect scripts that are used but have no script file.
module_names = {mod.__name__ for mod, info in addons}
@@ -1187,6 +1207,54 @@ class WM_OT_addon_install(bpy.types.Operator):
return {'RUNNING_MODAL'}
+class WM_OT_addon_remove(bpy.types.Operator):
+ "Disable an addon"
+ bl_idname = "wm.addon_remove"
+ bl_label = "Remove Add-On"
+
+ module = StringProperty(name="Module", description="Module name of the addon to remove")
+
+ @staticmethod
+ def path_from_addon(module):
+ for mod in addon_utils.modules(USERPREF_PT_addons._addons_fake_modules):
+ if mod.__name__ == module:
+ filepath = mod.__file__
+ if os.path.exists(filepath):
+ if os.path.splitext(os.path.basename(filepath))[0] == "__init__":
+ return os.path.dirname(filepath), True
+ else:
+ return filepath, False
+ return None, False
+
+ def execute(self, context):
+ path, isdir = __class__.path_from_addon(self.module)
+ if path is None:
+ self.report('WARNING', "Addon path %r could not be found" % path)
+ return {'CANCELLED'}
+
+ # incase its enabled
+ addon_utils.disable(self.module)
+
+ import shutil
+ if isdir:
+ shutil.rmtree(path)
+ else:
+ os.remove(path)
+
+ context.area.tag_redraw()
+ return {'FINISHED'}
+
+ # lame confirmation check
+ def draw(self, context):
+ self.layout.label(text="Remove Addon: %r?" % self.module)
+ path, isdir = __class__.path_from_addon(self.module)
+ self.layout.label(text="Path: %r" % path)
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ return wm.invoke_props_dialog(self, width=600)
+
+
class WM_OT_addon_expand(bpy.types.Operator):
"Display more information on this add-on"
bl_idname = "wm.addon_expand"
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 44b75f6d75e..8dd28909595 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -778,10 +778,16 @@ class VIEW3D_MT_object_specials(bpy.types.Menu):
if obj.type == 'CAMERA':
layout.operator_context = 'INVOKE_REGION_WIN'
- props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
- props.data_path_iter = "selected_editable_objects"
- props.data_path_item = "data.lens"
- props.input_scale = 0.1
+ if obj.data.type == 'PERSP':
+ props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
+ props.data_path_iter = "selected_editable_objects"
+ props.data_path_item = "data.lens"
+ props.input_scale = 0.1
+ else:
+ props = layout.operator("wm.context_modal_mouse", text="Camera Lens Scale")
+ props.data_path_iter = "selected_editable_objects"
+ props.data_path_item = "data.ortho_scale"
+ props.input_scale = 0.01
if not obj.data.dof_object:
#layout.label(text="Test Has DOF obj");
@@ -1104,17 +1110,18 @@ class VIEW3D_MT_sculpt(bpy.types.Menu):
layout.operator_menu_enum("brush.curve_preset", "shape")
layout.separator()
- sculpt_tool = brush.sculpt_tool
+ if brush is not None: # unlikely but can happen
+ sculpt_tool = brush.sculpt_tool
- if sculpt_tool != 'GRAB':
- layout.prop_menu_enum(brush, "stroke_method")
+ if sculpt_tool != 'GRAB':
+ layout.prop_menu_enum(brush, "stroke_method")
- if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
- layout.prop_menu_enum(brush, "direction")
+ if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
+ layout.prop_menu_enum(brush, "direction")
- if sculpt_tool == 'LAYER':
- layout.prop(brush, "use_persistent")
- layout.operator("sculpt.set_persistent_base")
+ if sculpt_tool == 'LAYER':
+ layout.prop(brush, "use_persistent")
+ layout.operator("sculpt.set_persistent_base")
layout.separator()
layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
@@ -1249,7 +1256,7 @@ class VIEW3D_MT_pose(bpy.types.Menu):
layout.separator()
layout.menu("VIEW3D_MT_pose_showhide")
- layout.operator_menu_enum("pose.flags_set", 'mode', text="Bone Settings")
+ layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
class VIEW3D_MT_pose_transform(bpy.types.Menu):
@@ -1370,6 +1377,49 @@ class VIEW3D_MT_pose_apply(bpy.types.Menu):
layout.operator("pose.visual_transform_apply")
+class BoneOptions:
+ def draw(self, context):
+ layout = self.layout
+
+ options = [
+ "show_wire",
+ "use_deform",
+ "use_envelope_multiply",
+ "use_inherit_rotation",
+ "use_inherit_scale",
+ ]
+
+ if context.mode == 'EDIT_ARMATURE':
+ bone_props = bpy.types.EditBone.bl_rna.properties
+ data_path_iter = "selected_bones"
+ opt_suffix = ""
+ options.append("lock")
+ else: # posemode
+ bone_props = bpy.types.Bone.bl_rna.properties
+ data_path_iter = "selected_pose_bones"
+ opt_suffix = "bone."
+
+ for opt in options:
+ props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name)
+ props.data_path_iter = data_path_iter
+ props.data_path_item = opt_suffix + opt
+ props.type = self.type
+
+
+class VIEW3D_MT_bone_options_toggle(bpy.types.Menu, BoneOptions):
+ bl_label = "Toggle Bone Options"
+ type = 'TOGGLE'
+
+
+class VIEW3D_MT_bone_options_enable(bpy.types.Menu, BoneOptions):
+ bl_label = "Enable Bone Options"
+ type = 'ENABLE'
+
+
+class VIEW3D_MT_bone_options_disable(bpy.types.Menu, BoneOptions):
+ bl_label = "Disable Bone Options"
+ type = 'DISABLE'
+
# ********** Edit Menus, suffix from ob.type **********
@@ -1963,7 +2013,7 @@ class VIEW3D_MT_edit_armature(bpy.types.Menu):
layout.separator()
- layout.operator_menu_enum("armature.flags_set", "mode", text="Bone Settings")
+ layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
class VIEW3D_MT_armature_specials(bpy.types.Menu):
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 503a1d806ac..52eb76d0710 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -997,7 +997,11 @@ class VIEW3D_PT_tools_brush_appearance(PaintPanel, bpy.types.Panel):
@classmethod
def poll(cls, context):
- return (context.sculpt_object and context.tool_settings.sculpt) or (context.vertex_paint_object and context.tool_settings.vertex_paint) or (context.weight_paint_object and context.tool_settings.weight_paint) or (context.image_paint_object and context.tool_settings.image_paint)
+ ts = context.tool_settings
+ return ((context.sculpt_object and ts.sculpt) or
+ (context.vertex_paint_object and ts.vertex_paint) or
+ (context.weight_paint_object and ts.weight_paint) or
+ (context.image_paint_object and ts.image_paint))
def draw(self, context):
layout = self.layout
@@ -1005,6 +1009,10 @@ class VIEW3D_PT_tools_brush_appearance(PaintPanel, bpy.types.Panel):
settings = __class__.paint_settings(context)
brush = settings.brush
+ if brush is None: # unlikely but can happen
+ layout.label(text="Brush Unset")
+ return
+
col = layout.column()
if context.sculpt_object and context.tool_settings.sculpt: