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:
Diffstat (limited to 'release')
-rw-r--r--release/scripts/io/export_fbx.py16
-rw-r--r--release/scripts/io/export_mdd.py2
-rw-r--r--release/scripts/io/netrender/balancing.py10
-rw-r--r--release/scripts/io/netrender/client.py1
-rw-r--r--release/scripts/io/netrender/master.py20
-rw-r--r--release/scripts/io/netrender/master_html.py2
-rw-r--r--release/scripts/io/netrender/model.py21
-rw-r--r--release/scripts/io/netrender/ui.py29
-rw-r--r--release/scripts/modules/bpy/utils.py17
-rw-r--r--release/scripts/modules/bpy_types.py18
-rw-r--r--release/scripts/modules/graphviz_export.py10
-rw-r--r--release/scripts/modules/rigify/__init__.py606
-rw-r--r--release/scripts/modules/rigify/arm_biped_generic.py (renamed from release/scripts/modules/rigify/arm.py)28
-rw-r--r--release/scripts/modules/rigify/copy.py66
-rw-r--r--release/scripts/modules/rigify/delta.py41
-rw-r--r--release/scripts/modules/rigify/finger_curl.py (renamed from release/scripts/modules/rigify/finger.py)26
-rw-r--r--release/scripts/modules/rigify/leg_biped_generic.py (renamed from release/scripts/modules/rigify/leg.py)60
-rw-r--r--release/scripts/modules/rigify/neck_flex.py (renamed from release/scripts/modules/rigify/neck.py)78
-rw-r--r--release/scripts/modules/rigify/palm_curl.py (renamed from release/scripts/modules/rigify/palm.py)48
-rw-r--r--release/scripts/modules/rigify/spine_pivot_flex.py (renamed from release/scripts/modules/rigify/spine.py)21
-rw-r--r--release/scripts/modules/rigify_utils.py472
-rw-r--r--release/scripts/modules/rna_prop_ui.py2
-rw-r--r--release/scripts/op/add_mesh_torus.py2
-rw-r--r--release/scripts/op/screen_play_rendered_anim.py99
-rw-r--r--release/scripts/op/wm.py2
-rw-r--r--release/scripts/ui/properties_data_armature.py4
-rw-r--r--release/scripts/ui/properties_data_bone.py2
-rw-r--r--release/scripts/ui/properties_data_mesh.py36
-rw-r--r--release/scripts/ui/properties_material.py6
-rw-r--r--release/scripts/ui/properties_object.py4
-rw-r--r--release/scripts/ui/properties_object_constraint.py2
-rw-r--r--release/scripts/ui/properties_particle.py40
-rw-r--r--release/scripts/ui/properties_physics_common.py4
-rw-r--r--release/scripts/ui/properties_physics_fluid.py2
-rw-r--r--release/scripts/ui/properties_render.py18
-rw-r--r--release/scripts/ui/properties_scene.py13
-rw-r--r--release/scripts/ui/properties_texture.py4
-rw-r--r--release/scripts/ui/space_dopesheet.py10
-rw-r--r--release/scripts/ui/space_filebrowser.py12
-rw-r--r--release/scripts/ui/space_graph.py22
-rw-r--r--release/scripts/ui/space_image.py26
-rw-r--r--release/scripts/ui/space_info.py96
-rw-r--r--release/scripts/ui/space_logic.py4
-rw-r--r--release/scripts/ui/space_nla.py8
-rw-r--r--release/scripts/ui/space_node.py8
-rw-r--r--release/scripts/ui/space_outliner.py8
-rw-r--r--release/scripts/ui/space_sequencer.py46
-rw-r--r--release/scripts/ui/space_text.py8
-rw-r--r--release/scripts/ui/space_time.py29
-rw-r--r--release/scripts/ui/space_userpref.py22
-rw-r--r--release/scripts/ui/space_view3d.py64
-rw-r--r--release/scripts/ui/space_view3d_toolbar.py56
52 files changed, 1364 insertions, 887 deletions
diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py
index c821e1d4fad..6fa81fb41ce 100644
--- a/release/scripts/io/export_fbx.py
+++ b/release/scripts/io/export_fbx.py
@@ -3363,10 +3363,10 @@ class ExportFBX(bpy.types.Operator):
EXP_OBS_SELECTED = BoolProperty(name="Selected Objects", description="Export selected objects on visible layers", default=True)
# EXP_OBS_SCENE = BoolProperty(name="Scene Objects", description="Export all objects in this scene", default=True)
- _SCALE = FloatProperty(name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0)
- _XROT90 = BoolProperty(name="Rot X90", description="Rotate all objects 90 degrese about the X axis", default=True)
- _YROT90 = BoolProperty(name="Rot Y90", description="Rotate all objects 90 degrese about the Y axis", default=False)
- _ZROT90 = BoolProperty(name="Rot Z90", description="Rotate all objects 90 degrese about the Z axis", default=False)
+ TX_SCALE = FloatProperty(name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0)
+ TX_XROT90 = BoolProperty(name="Rot X90", description="Rotate all objects 90 degrese about the X axis", default=True)
+ TX_YROT90 = BoolProperty(name="Rot Y90", description="Rotate all objects 90 degrese about the Y axis", default=False)
+ TX_ZROT90 = BoolProperty(name="Rot Z90", description="Rotate all objects 90 degrese about the Z axis", default=False)
EXP_EMPTY = BoolProperty(name="Empties", description="Export empty objects", default=True)
EXP_CAMERA = BoolProperty(name="Cameras", description="Export camera objects", default=True)
EXP_LAMP = BoolProperty(name="Lamps", description="Export lamp objects", default=True)
@@ -3397,10 +3397,10 @@ class ExportFBX(bpy.types.Operator):
raise Exception("path not set")
GLOBAL_MATRIX = mtx4_identity
- GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties._SCALE
- if self.properties._XROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n
- if self.properties._YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n
- if self.properties._ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n
+ GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties.TX_SCALE
+ if self.properties.TX_XROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n
+ if self.properties.TX_YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n
+ if self.properties.TX_ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n
write(self.properties.path,
None, # XXX
diff --git a/release/scripts/io/export_mdd.py b/release/scripts/io/export_mdd.py
index c160b94e546..9753a63ce48 100644
--- a/release/scripts/io/export_mdd.py
+++ b/release/scripts/io/export_mdd.py
@@ -163,7 +163,7 @@ class ExportMDD(bpy.types.Operator):
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
- path = StringProperty(name="File Path", description="File path used for exporting the MDD file", maxlen= 1024, default= "tmp.mdd")
+ path = StringProperty(name="File Path", description="File path used for exporting the MDD file", maxlen= 1024, default= "")
fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default= 25)
start_frame = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe,max=maxframe,default=1)
end_frame = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default= 250)
diff --git a/release/scripts/io/netrender/balancing.py b/release/scripts/io/netrender/balancing.py
index f093815d8a8..aa0ffcd3f67 100644
--- a/release/scripts/io/netrender/balancing.py
+++ b/release/scripts/io/netrender/balancing.py
@@ -84,6 +84,16 @@ class RatingUsage(RatingRule):
# less usage is better
return job.usage / job.priority
+class RatingUsageByCategory(RatingRule):
+ def __init__(self, get_jobs):
+ self.getJobs = get_jobs
+ def rate(self, job):
+ total_category_usage = sum([j.usage for j in self.getJobs() if j.category == job.category])
+ maximum_priority = max([j.priority for j in self.getJobs() if j.category == job.category])
+
+ # less usage is better
+ return total_category_usage / maximum_priority
+
class NewJobPriority(PriorityRule):
def __init__(self, limit = 1):
self.limit = limit
diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py
index f39beadfe57..829d75b6c67 100644
--- a/release/scripts/io/netrender/client.py
+++ b/release/scripts/io/netrender/client.py
@@ -150,6 +150,7 @@ def clientSendJob(conn, scene, anim = False):
# print(job.files)
job.name = job_name
+ job.category = netsettings.job_category
for slave in netrender.blacklist:
job.blacklist.append(slave.id)
diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py
index 7abca023e50..504430a7e0c 100644
--- a/release/scripts/io/netrender/master.py
+++ b/release/scripts/io/netrender/master.py
@@ -60,17 +60,9 @@ class MRenderSlave(netrender.model.RenderSlave):
self.job = None
class MRenderJob(netrender.model.RenderJob):
- def __init__(self, job_id, job_type, name, files, chunks = 1, priority = 1, blacklist = []):
- super().__init__()
+ def __init__(self, job_id, job_info):
+ super().__init__(job_info)
self.id = job_id
- self.type = job_type
- self.name = name
- self.files = files
- self.frames = []
- self.chunks = chunks
- self.priority = priority
- self.usage = 0.0
- self.blacklist = blacklist
self.last_dispatched = time.time()
# force one chunk for process jobs
@@ -80,7 +72,7 @@ class MRenderJob(netrender.model.RenderJob):
# special server properties
self.last_update = 0
self.save_path = ""
- self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files}
+ self.files_map = {path: MRenderFile(path, start, end) for path, start, end in job_info.files}
self.status = JOB_WAITING
def save(self):
@@ -393,7 +385,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
job_id = self.server.nextJobID()
- job = MRenderJob(job_id, job_info.type, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
+ job = MRenderJob(job_id, job_info)
for frame in job_info.frames:
frame = job.addFrame(frame.number, frame.command)
@@ -635,6 +627,7 @@ class RenderMasterServer(http.server.HTTPServer):
self.slave_timeout = 2
self.balancer = netrender.balancing.Balancer()
+ self.balancer.addRule(netrender.balancing.RatingUsageByCategory(self.getJobs))
self.balancer.addRule(netrender.balancing.RatingUsage())
self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob())
self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves, limit = 0.9))
@@ -707,6 +700,9 @@ class RenderMasterServer(http.server.HTTPServer):
def balance(self):
self.balancer.balance(self.jobs)
+ def getJobs(self):
+ return self.jobs
+
def countJobs(self, status = JOB_QUEUED):
total = 0
for j in self.jobs:
diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py
index 2fc6cd66f93..c94d1e2f72d 100644
--- a/release/scripts/io/netrender/master_html.py
+++ b/release/scripts/io/netrender/master_html.py
@@ -71,6 +71,7 @@ def get(handler):
startTable()
headerTable(
"name",
+ "category",
"priority",
"usage",
"wait",
@@ -88,6 +89,7 @@ def get(handler):
results = job.framesStatus()
rowTable(
link(job.name, "/html/job" + job.id),
+ job.category,
job.priority,
"%0.1f%%" % (job.usage * 100),
"%is" % int(time.time() - job.last_dispatched),
diff --git a/release/scripts/io/netrender/model.py b/release/scripts/io/netrender/model.py
index cf13fe1e1fa..7d0fff5a83a 100644
--- a/release/scripts/io/netrender/model.py
+++ b/release/scripts/io/netrender/model.py
@@ -99,18 +99,29 @@ JOB_TYPES = {
}
class RenderJob:
- def __init__(self):
+ def __init__(self, job_info = None):
self.id = ""
self.type = JOB_BLENDER
self.name = ""
+ self.category = "None"
self.files = []
- self.frames = []
self.chunks = 0
self.priority = 0
- self.usage = 0.0
self.blacklist = []
+
+ self.usage = 0.0
self.last_dispatched = 0.0
-
+ self.frames = []
+
+ if job_info:
+ self.type = job_info.type
+ self.name = job_info.name
+ self.category = job_info.category
+ self.files = job_info.files
+ self.chunks = job_info.chunks
+ self.priority = job_info.priority
+ self.blacklist = job_info.blacklist
+
def addFile(self, file_path, start=-1, end=-1):
self.files.append((file_path, start, end))
@@ -167,6 +178,7 @@ class RenderJob:
"id": self.id,
"type": self.type,
"name": self.name,
+ "category": self.category,
"files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= max_frame and f[2] >= min_frame)],
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
"chunks": self.chunks,
@@ -185,6 +197,7 @@ class RenderJob:
job.id = data["id"]
job.type = data["type"]
job.name = data["name"]
+ job.category = data["category"]
job.files = data["files"]
job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
job.chunks = data["chunks"]
diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py
index 081d9952871..fd9ce0fcc32 100644
--- a/release/scripts/io/netrender/ui.py
+++ b/release/scripts/io/netrender/ui.py
@@ -71,7 +71,7 @@ class RENDER_PT_network_settings(RenderButtonsPanel):
if scene.network_render.mode == "RENDER_MASTER":
col.prop(scene.network_render, "server_broadcast")
else:
- col.operator("render.netclientscan", icon="ICON_FILE_REFRESH", text="")
+ col.operator("render.netclientscan", icon='FILE_REFRESH', text="")
@rnaType
class RENDER_PT_network_job(RenderButtonsPanel):
@@ -93,10 +93,11 @@ class RENDER_PT_network_job(RenderButtonsPanel):
split = layout.split()
col = split.column()
- col.operator("render.netclientanim", icon='ICON_RENDER_ANIMATION')
- col.operator("render.netclientsend", icon="ICON_FILE_BLEND")
- col.operator("render.netclientweb", icon="ICON_QUESTION")
+ col.operator("render.netclientanim", icon='RENDER_ANIMATION')
+ col.operator("render.netclientsend", icon='FILE_BLEND')
+ col.operator("render.netclientweb", icon='QUESTION')
col.prop(scene.network_render, "job_name")
+ col.prop(scene.network_render, "job_category")
row = col.row()
row.prop(scene.network_render, "priority")
row.prop(scene.network_render, "chunks")
@@ -120,8 +121,8 @@ class RENDER_PT_network_slaves(RenderButtonsPanel):
row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2)
sub = row.column(align=True)
- sub.operator("render.netclientslaves", icon="ICON_FILE_REFRESH", text="")
- sub.operator("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="")
+ sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="")
+ sub.operator("render.netclientblacklistslave", icon='ZOOMOUT', text="")
if len(netrender.slaves) == 0 and len(netsettings.slaves) > 0:
while(len(netsettings.slaves) > 0):
@@ -156,7 +157,7 @@ class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2)
sub = row.column(align=True)
- sub.operator("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="")
+ sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="")
if len(netrender.blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
while(len(netsettings.slaves_blacklist) > 0):
@@ -191,10 +192,10 @@ class RENDER_PT_network_jobs(RenderButtonsPanel):
row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2)
sub = row.column(align=True)
- sub.operator("render.netclientstatus", icon="ICON_FILE_REFRESH", text="")
- sub.operator("render.netclientcancel", icon="ICON_ZOOMOUT", text="")
- sub.operator("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="")
- sub.operator("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="")
+ sub.operator("render.netclientstatus", icon='FILE_REFRESH', text="")
+ sub.operator("render.netclientcancel", icon='ZOOMOUT', text="")
+ sub.operator("render.netclientcancelall", icon='PANEL_CLOSE', text="")
+ sub.operator("render.netclientdownload", icon='RENDER_ANIMATION', text="")
if len(netrender.jobs) == 0 and len(netsettings.jobs) > 0:
while(len(netsettings.jobs) > 0):
@@ -264,6 +265,12 @@ NetRenderSettings.StringProperty( attr="job_name",
maxlen = 128,
default = "[default]")
+NetRenderSettings.StringProperty( attr="job_category",
+ name="Job category",
+ description="Category of the job",
+ maxlen = 128,
+ default = "")
+
NetRenderSettings.IntProperty( attr="chunks",
name="Chunks",
description="Number of frame to dispatch to each slave in one chunk",
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 76e8b011628..ad0fa4e8ba5 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -53,6 +53,23 @@ def clean_name(name, replace="_"):
name = name.replace(ch, replace)
return name
+def display_name(name):
+ '''
+ Only capitalize all lowercase names, mixed case use them as is.
+ should work with filenames and module names.
+ '''
+ name_base = os.path.splitext(name)[0]
+
+ # string replacements
+ name_base = name_base.replace("_colon_", ":")
+
+ name_base = name_base.replace("_", " ")
+
+ if name_base.lower() == name_base:
+ return ' '.join([w[0].upper() + w[1:] for w in name_base.split()])
+ else:
+ return name_base
+
# base scripts
_scripts = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 28ea2d71be8..239990e2bd5 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -288,21 +288,7 @@ class Menu(StructRNA):
# hard coded to set the operators 'path' to the filename.
import os
-
- def path_to_name(f):
- ''' Only capitalize all lowercase names, mixed case use them as is.
- '''
- f_base = os.path.splitext(f)[0]
-
- # string replacements
- f_base = f_base.replace("_colon_", ":")
-
- f_base = f_base.replace("_", " ")
-
- if f_base.lower() == f_base:
- return ' '.join([w[0].upper() + w[1:] for w in f_base.split()])
- else:
- return f_base
+ import bpy.utils
layout = self.layout
@@ -318,7 +304,7 @@ class Menu(StructRNA):
if f.startswith("."):
continue
- layout.operator(operator, text=path_to_name(f)).path = path
+ layout.operator(operator, text=bpy.utils.display_name(f)).path = path
def draw_preset(self, context):
'''Define these on the subclass
diff --git a/release/scripts/modules/graphviz_export.py b/release/scripts/modules/graphviz_export.py
index 92eb427f8d2..f39095b9eba 100644
--- a/release/scripts/modules/graphviz_export.py
+++ b/release/scripts/modules/graphviz_export.py
@@ -48,7 +48,7 @@ def compat_str(text, line_length=0):
#text = text.replace(']', ']\n')
text = text.replace("\n", "\\n")
text = text.replace('"', '\\"')
- return "* " + text
+ return text
def graph_armature(obj, path, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=True, XTRA_INFO=True):
@@ -150,16 +150,16 @@ def graph_armature(obj, path, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=True,
if animation_data:
fcurve_drivers = [fcurve_driver for fcurve_driver in animation_data.drivers]
- fcurve_drivers.sort(key=lambda fcurve_driver: fcurve_driver.rna_path)
+ fcurve_drivers.sort(key=lambda fcurve_driver: fcurve_driver.data_path)
for fcurve_driver in fcurve_drivers:
- rna_path = fcurve_driver.rna_path
+ rna_path = fcurve_driver.data_path
pbone = rna_path_as_pbone(rna_path)
if pbone:
for target in fcurve_driver.driver.targets:
- pbone_target = rna_path_as_pbone(target.rna_path)
- rna_path_target = target.rna_path
+ pbone_target = rna_path_as_pbone(target.data_path)
+ rna_path_target = target.data_path
if pbone_target:
opts = ['dir=forward', "weight=1", "arrowhead=normal", "arrowtail=none", "constraint=false", 'color="blue"', "labelfontsize=4"] # ,
display_source = rna_path.replace("pose.bones", "")
diff --git a/release/scripts/modules/rigify/__init__.py b/release/scripts/modules/rigify/__init__.py
index af345b5e546..33a2f4c007e 100644
--- a/release/scripts/modules/rigify/__init__.py
+++ b/release/scripts/modules/rigify/__init__.py
@@ -23,376 +23,96 @@ from Mathutils import Vector
# TODO, have these in a more general module
from rna_prop_ui import rna_idprop_ui_prop_get
-
-empty_layer = [False] * 32
-
-
-def auto_class(slots, name="ContainerClass", class_dict=None):
-
- if class_dict:
- class_dict = class_dict.copy()
- else:
- class_dict = {}
-
- class_dict["__slots__"] = tuple(slots)
-
- return type(name, (object,), class_dict)
-
-
-def auto_class_instance(slots, name="ContainerClass", class_dict=None):
- return auto_class(slots, name, class_dict)()
-
-
-def _bone_class_instance_update(self):
- ''' Re-Assigns bones from the blender data
- '''
- arm = self.obj.data
- bbones = arm.bones
- pbones = self.obj.pose.bones
- ebones = arm.edit_bones
-
- for member in self.attr_names:
- name = getattr(self, member, None)
- if name is not None:
- setattr(self, member + "_b", bbones.get(name, None))
- setattr(self, member + "_p", pbones.get(name, None))
- setattr(self, member + "_e", ebones.get(name, None))
-
-
-def _bone_class_instance_rename(self, attr, new_name):
- ''' Rename bones, editmode only
- '''
-
- if self.obj.mode != 'EDIT':
- raise Exception("Only rename in editmode supported")
-
- ebone = getattr(self, attr + "_e")
- ebone.name = new_name
-
- # we may not get what is asked for so get the name from the editbone
- setattr(self, attr, ebone.name)
-
-
-def _bone_class_instance_copy(self, from_fmt="%s", to_fmt="%s", exclude_attrs=(), base_names=None):
- from_name_ls = []
- new_name_ls = []
- new_slot_ls = []
-
- for attr in self.attr_names:
-
- if attr in exclude_attrs:
- continue
+SPECIAL_TYPES = "root",
+
+class RigifyError(Exception):
+ """Exception raised for errors in the metarig.
+ """
+ def __init__(self, message):
+ self.message = message
+ def __str__(self):
+ return repr(self.message)
+
+def submodule_func_from_type(bone_type):
+ type_pair = bone_type.split(".")
+
+ # 'leg.ik' will look for an ik function in the leg module
+ # 'leg' will look up leg.main
+ if len(type_pair) == 1:
+ type_pair = type_pair[0], "main"
+
+ submod_name, func_name = type_pair
+
+ # from rigify import leg
+ try:
+ submod = __import__(name="%s.%s" % (__package__, submod_name), fromlist=[submod_name])
+ except ImportError:
+ raise RigifyError("python module for type '%s' not found" % submod_name)
- bone_name_orig = getattr(self, attr)
- ebone = getattr(self, attr + "_e")
- # orig_names[attr] = bone_name_orig
-
- # insert formatting
- if from_fmt != "%s":
- bone_name = from_fmt % bone_name_orig
- ebone.name = bone_name
- bone_name = ebone.name # cant be sure we get what we ask for
- else:
- bone_name = bone_name_orig
-
- setattr(self, attr, bone_name)
-
- new_slot_ls.append(attr)
- from_name_ls.append(bone_name)
- if base_names:
- bone_name_orig = base_names[bone_name_orig]
- new_name_ls.append(to_fmt % bone_name_orig)
-
- new_bones = copy_bone_simple_list(self.obj.data, from_name_ls, new_name_ls, True)
- new_bc = bone_class_instance(self.obj, new_slot_ls)
-
- for i, attr in enumerate(new_slot_ls):
- ebone = new_bones[i]
- setattr(new_bc, attr + "_e", ebone)
- setattr(new_bc, attr, ebone.name)
-
- return new_bc
-
-
-def _bone_class_instance_names(self):
- return [getattr(self, attr) for attr in self.attr_names]
-
-
-def _bone_class_instance_blend(self, from_bc, to_bc, target_bone=None, target_prop="blend"):
- '''
- Use for blending bone chains.
+ reload(submod)
+ return submod, getattr(submod, func_name)
- blend_target = (bone_name, bone_property)
- default to the last bone, blend prop
- XXX - toggles editmode, need to re-validate all editbones :(
- '''
-
- if self.attr_names != from_bc.attr_names or self.attr_names != to_bc.attr_names:
- raise Exception("can only blend between matching chains")
-
- apply_bones = [getattr(self, attr) for attr in self.attr_names]
- from_bones = [getattr(from_bc, attr) for attr in from_bc.attr_names]
- to_bones = [getattr(to_bc, attr) for attr in to_bc.attr_names]
-
- blend_bone_list(self.obj, apply_bones, from_bones, to_bones, target_bone, target_prop)
-
-
-def bone_class_instance(obj, slots, name="BoneContainer"):
+def submodule_types():
+ import os
+ submodules = []
+ files = os.listdir(os.path.dirname(__file__))
+ for f in files:
+ if not f.startswith("_") and f.endswith(".py"):
+ submodules.append(f[:-3])
- if len(slots) != len(set(slots)):
- raise Exception("duplicate entries found %s" % attr_names)
-
- attr_names = tuple(slots) # dont modify the original
- slots = list(slots) # dont modify the original
- for i in range(len(slots)):
- member = slots[i]
- slots.append(member + "_b") # bone bone
- slots.append(member + "_p") # pose bone
- slots.append(member + "_e") # edit bone
-
- class_dict = { \
- "obj": obj, \
- "attr_names": attr_names, \
- "update": _bone_class_instance_update, \
- "rename": _bone_class_instance_rename, \
- "names": _bone_class_instance_names, \
- "copy": _bone_class_instance_copy, \
- "blend": _bone_class_instance_blend, \
- }
-
- instance = auto_class_instance(slots, name, class_dict)
- return instance
-
-
-def get_bone_data(obj, bone_name):
- arm = obj.data
- pbone = obj.pose.bones[bone_name]
- if obj.mode == 'EDIT':
- bone = arm.edit_bones[bone_name]
- else:
- bone = arm.bones[bone_name]
-
- return arm, pbone, bone
+ return sorted(submodules)
-def copy_bone_simple(arm, from_bone, name, parent=False):
- ebone = arm.edit_bones[from_bone]
- ebone_new = arm.edit_bones.new(name)
-
- if parent:
- ebone_new.connected = ebone.connected
- ebone_new.parent = ebone.parent
-
- ebone_new.head = ebone.head
- ebone_new.tail = ebone.tail
- ebone_new.roll = ebone.roll
- return ebone_new
-
-
-def copy_bone_simple_list(arm, from_bones, to_bones, parent=False):
-
- if len(from_bones) != len(to_bones):
- raise Exception("bone list sizes must match")
-
- copy_bones = [copy_bone_simple(arm, bone_name, to_bones[i], True) for i, bone_name in enumerate(from_bones)]
-
- # now we need to re-parent
- for ebone in copy_bones:
- parent = ebone.parent
- if parent:
- try:
- i = from_bones.index(parent.name)
- except:
- i = -1
-
- if i == -1:
- ebone.parent = None
- else:
- ebone.parent = copy_bones[i]
-
- return copy_bones
-
-
-def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, target_prop="blend"):
-
- if obj.mode == 'EDIT':
- raise Exception("blending cant be called in editmode")
-
- if len(apply_bones) != len(from_bones):
- raise Exception("lists differ in length (from -> apply): \n\t%s\n\t%s" % (from_bones, apply_bones))
- if len(apply_bones) != len(to_bones):
- raise Exception("lists differ in length (to -> apply): \n\t%s\n\t%s" % (to_bones, apply_bones))
-
- # setup the blend property
- if target_bone is None:
- target_bone = apply_bones[-1] # default to the last bone
-
- prop_pbone = obj.pose.bones[target_bone]
- if prop_pbone.get(target_bone, None) is None:
- prop = rna_idprop_ui_prop_get(prop_pbone, target_prop, create=True)
- prop_pbone[target_prop] = 0.5
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
-
- driver_path = prop_pbone.path_to_id() + ('["%s"]' % target_prop)
-
- def blend_target(driver):
- tar = driver.targets.new()
- tar.name = target_bone
- tar.id_type = 'OBJECT'
- tar.id = obj
- tar.rna_path = driver_path
-
- def blend_location(new_pbone, from_bone_name, to_bone_name):
- con = new_pbone.constraints.new('COPY_LOCATION')
- con.target = obj
- con.subtarget = from_bone_name
-
- con = new_pbone.constraints.new('COPY_LOCATION')
- con.target = obj
- con.subtarget = to_bone_name
-
- fcurve = con.driver_add("influence", 0)
- driver = fcurve.driver
- driver.type = 'AVERAGE'
- fcurve.modifiers.remove(0) # grr dont need a modifier
-
- blend_target(driver)
-
- def blend_rotation(new_pbone, from_bone_name, to_bone_name):
- con = new_pbone.constraints.new('COPY_ROTATION')
- con.target = obj
- con.subtarget = from_bone_name
-
- con = new_pbone.constraints.new('COPY_ROTATION')
- con.target = obj
- con.subtarget = to_bone_name
-
- fcurve = con.driver_add("influence", 0)
- driver = fcurve.driver
- driver.type = 'AVERAGE'
- fcurve.modifiers.remove(0) # grr dont need a modifier
-
- blend_target(driver)
-
- for i, new_bone_name in enumerate(apply_bones):
- from_bone_name = from_bones[i]
- to_bone_name = to_bones[i]
-
- # allow skipping some bones by having None in the list
- if None in (new_bone_name, from_bone_name, to_bone_name):
- continue
-
- new_pbone = obj.pose.bones[new_bone_name]
-
- # if the bone is connected or its location is totally locked then dont add location blending.
- if not (new_pbone.bone.connected or (False not in new_pbone.lock_location)):
- blend_location(new_pbone, from_bone_name, to_bone_name)
-
- if not (False not in new_pbone.lock_rotation): # TODO. 4D chech?
- blend_rotation(new_pbone, from_bone_name, to_bone_name)
-
-
-def add_stretch_to(obj, from_name, to_name, name):
+def validate_rig(context, obj):
'''
- Adds a bone that stretches from one to another
+ Makes no changes
+ only runs the metarig definitions and reports errors
'''
-
- mode_orig = obj.mode
- bpy.ops.object.mode_set(mode='EDIT')
-
- arm = obj.data
- stretch_ebone = arm.edit_bones.new(name)
- stretch_name = stretch_ebone.name
- del name
-
- head = stretch_ebone.head = arm.edit_bones[from_name].head.copy()
- #tail = stretch_ebone.tail = arm.edit_bones[to_name].head.copy()
-
- # annoying exception for zero length bones, since its using stretch_to the rest pose doesnt really matter
- #if (head - tail).length < 0.1:
- if 1:
- tail = stretch_ebone.tail = arm.edit_bones[from_name].tail.copy()
-
-
- # Now for the constraint
- bpy.ops.object.mode_set(mode='OBJECT')
-
- stretch_pbone = obj.pose.bones[stretch_name]
-
- con = stretch_pbone.constraints.new('COPY_LOCATION')
- con.target = obj
- con.subtarget = from_name
-
- con = stretch_pbone.constraints.new('STRETCH_TO')
- con.target = obj
- con.subtarget = to_name
- con.original_length = (head - tail).length
- con.keep_axis = 'PLANE_X'
- con.volume = 'NO_VOLUME'
-
- bpy.ops.object.mode_set(mode=mode_orig)
+ type_found = False
- return stretch_name
-
-def add_pole_target_bone(obj, base_name, name, mode='CROSS'):
- '''
- Does not actually create a poll target, just the bone to use as a poll target
- '''
- mode_orig = obj.mode
- bpy.ops.object.mode_set(mode='EDIT')
-
- arm = obj.data
-
- poll_ebone = arm.edit_bones.new(base_name + "_poll")
- base_ebone = arm.edit_bones[base_name]
- poll_name = poll_ebone.name
- parent_ebone = base_ebone.parent
-
- base_head = base_ebone.head.copy()
- base_tail = base_ebone.tail.copy()
- base_dir = base_head - base_tail
-
- parent_head = parent_ebone.head.copy()
- parent_tail = parent_ebone.tail.copy()
- parent_dir = parent_head - parent_tail
+ for pbone in obj.pose.bones:
+ bone_name = pbone.name
+ bone_type = pbone.get("type", "")
- distance = (base_dir.length + parent_dir.length)
-
- if mode == 'CROSS':
- # direction from the angle of the joint
- offset = base_dir.copy().normalize() - parent_dir.copy().normalize()
- offset.length = distance
- elif mode == 'ZAVERAGE':
- # between both bones Z axis
- z_axis_a = base_ebone.matrix.copy().rotationPart() * Vector(0.0, 0.0, -1.0)
- z_axis_b = parent_ebone.matrix.copy().rotationPart() * Vector(0.0, 0.0, -1.0)
- offset = (z_axis_a + z_axis_b).normalize() * distance
- else:
- # preset axis
- offset = Vector(0, 0, 0)
- if mode[0] == "+":
- val = distance
+ if bone_type:
+ bone_type_list = [bt for bt in bone_type.replace(",", " ").split()]
else:
- val = - distance
-
- setattr(offset, mode[1].lower(), val)
-
- poll_ebone.head = base_head + offset
- poll_ebone.tail = base_head + (offset * (1.0 - (1.0 / 4.0)))
+ bone_type_list = []
- bpy.ops.object.mode_set(mode=mode_orig)
+ for bone_type in bone_type_list:
+ if bone_type.split(".")[0] in SPECIAL_TYPES:
+ continue
- return poll_name
+ submod, type_func = submodule_func_from_type(bone_type)
+ reload(submod)
+ submod.metarig_definition(obj, bone_name)
+ type_found = True
+
+ # missing, - check for duplicate root bone.
+
+ if not type_found:
+ raise RigifyError("This rig has no 'type' properties defined on any pose bones, nothing to do")
def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
+ '''
+ Main function for generating
+ '''
from collections import OrderedDict
+ import rigify_utils
+ reload(rigify_utils)
+
+ # Not needed but catches any errors before duplicating
+ validate_rig(context, obj_orig)
global_undo = context.user_preferences.edit.global_undo
context.user_preferences.edit.global_undo = False
-
+ mode_orig = context.mode
+ rest_backup = obj_orig.data.pose_position
+ obj_orig.data.pose_position = 'REST'
+
+
bpy.ops.object.mode_set(mode='OBJECT')
scene = context.scene
@@ -404,7 +124,7 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
scene.objects.link(obj)
scene.objects.active = obj
obj.selected = True
-
+
if META_DEF:
obj_def = obj_orig.copy()
obj_def.data = obj_orig.data.copy()
@@ -435,6 +155,12 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
# value: [functions, ...]
# each function is from the module. eg leg.ik, arm.main
bone_typeinfos = {}
+
+ # key: bone name
+ # value: [new_bone_name, ...]
+ # where each bone with a 'type' stores a list of bones that it created
+ # ...needed so we can override the root parent
+ bone_genesis = {}
# inspect all bones and assign their definitions before modifying
for pbone in obj.pose.bones:
@@ -455,31 +181,17 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
bone_type_list[:] = []
for bone_type in bone_type_list:
-
- type_pair = bone_type.split(".")
-
- # 'leg.ik' will look for an ik function in the leg module
- # 'leg' will look up leg.main
- if len(type_pair) == 1:
- type_pair = type_pair[0], "main"
-
- submod_name, func_name = type_pair
-
- # from rigify import leg
- submod = __import__(name="%s.%s" % (__package__, submod_name), fromlist=[submod_name])
+ submod, type_func = submodule_func_from_type(bone_type)
reload(submod)
-
+ submod_name = submod.__name__
+
bone_def_dict = bone_definitions.setdefault(bone_name, {})
# Only calculate bone definitions once
if submod_name not in bone_def_dict:
- metarig_definition_func = getattr(submod, "metarig_definition")
- bone_def_dict[submod_name] = metarig_definition_func(obj, bone_name)
-
+ bone_def_dict[submod_name] = submod.metarig_definition(obj, bone_name)
bone_typeinfo = bone_typeinfos.setdefault(bone_name, [])
-
- type_func = getattr(submod, func_name)
bone_typeinfo.append((submod_name, type_func))
@@ -501,6 +213,8 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
# Only blend results from the same submodule, eg.
# leg.ik and arm.fk could not be blended.
results = OrderedDict()
+
+ bone_names_pre = set([bone.name for bone in arm.bones])
for submod_name, type_func in bone_typeinfos[bone_name]:
# this bones definition of the current typeinfo
@@ -525,15 +239,41 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
if len(result_submod) == 2:
blend_bone_list(obj, definition, result_submod[0], result_submod[1], target_bone=bone_name)
+
+ bone_names_post = set([bone.name for bone in arm.bones])
+
+ # Store which bones were created from this one
+ bone_genesis[bone_name] = list(bone_names_post - bone_names_pre)
+
+ # need a reverse lookup on bone_genesis so as to know immediately
+ # where a bone comes from
+ bone_genesis_reverse = {}
+ for bone_name, bone_children in bone_genesis.items():
+ for bone_child_name in bone_children:
+ bone_genesis_reverse[bone_child_name] = bone_name
+
+
if root_bone:
# assign all new parentless bones to this
bpy.ops.object.mode_set(mode='EDIT')
root_ebone = arm.edit_bones[root_bone]
for ebone in arm.edit_bones:
- if ebone.parent is None and ebone.name not in base_names:
+ bone_name = ebone.name
+ if ebone.parent is None and bone_name not in base_names:
+ # check for override
+ bone_creator = bone_genesis_reverse[bone_name]
+ pbone_creator = obj.pose.bones[bone_creator]
+ root_bone_override = pbone_creator.get("root", "")
+
+ if root_bone_override:
+ root_ebone_tmp = arm.edit_bones[root_bone_override]
+ else:
+ root_ebone_tmp = root_ebone
+
ebone.connected = False
- ebone.parent = root_ebone
+ ebone.parent = root_ebone_tmp
+
bpy.ops.object.mode_set(mode='OBJECT')
@@ -552,75 +292,24 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
con.target = obj
con.subtarget = bone_name
+ # would be 'REST' from when copied
+ obj_def.data.pose_position = 'POSE'
+
# Only for demo'ing
# obj.restrict_view = True
obj.data.draw_axes = False
+ bpy.ops.object.mode_set(mode=mode_orig)
+ obj_orig.data.pose_position = rest_backup
+ obj.data.pose_position = 'POSE'
context.user_preferences.edit.global_undo = global_undo
-
+
+
return obj
-def write_meta_rig(obj, func_name="metarig_template"):
- ''' Must be in editmode
- '''
- code = []
-
- code.append("def %s():" % func_name)
- code.append(" # generated by rigify.write_meta_rig")
- bpy.ops.object.mode_set(mode='EDIT')
- code.append(" bpy.ops.object.mode_set(mode='EDIT')")
-
- code.append(" obj = bpy.context.object")
- code.append(" arm = obj.data")
-
- arm = obj.data
- # write parents first
- bones = [(len(bone.parent_recursive), bone.name) for bone in arm.edit_bones]
- bones.sort(key=lambda item: item[0])
- bones = [item[1] for item in bones]
-
-
- for bone_name in bones:
- bone = arm.edit_bones[bone_name]
- code.append(" bone = arm.edit_bones.new('%s')" % bone.name)
- code.append(" bone.head[:] = %.4f, %.4f, %.4f" % bone.head.toTuple(4))
- code.append(" bone.tail[:] = %.4f, %.4f, %.4f" % bone.tail.toTuple(4))
- code.append(" bone.roll = %.4f" % bone.roll)
- code.append(" bone.connected = %s" % str(bone.connected))
- if bone.parent:
- code.append(" bone.parent = arm.edit_bones['%s']" % bone.parent.name)
-
- bpy.ops.object.mode_set(mode='OBJECT')
- code.append("")
- code.append(" bpy.ops.object.mode_set(mode='OBJECT')")
-
- for bone_name in bones:
- pbone = obj.pose.bones[bone_name]
- pbone_written = False
-
- # Only 1 level of props, simple types supported
- for key, value in pbone.items():
- if key.startswith("_"):
- continue
-
- if type(value) not in (float, str, int):
- print("Unsupported ID Prop:", str((key, value)))
- continue
-
- if type(value) == str:
- value = "'" + value + "'"
-
- if not pbone_written: # only write bones we need
- code.append(" pbone = obj.pose.bones['%s']" % bone_name)
-
- code.append(" pbone['%s'] = %s" % (key, value))
-
- return "\n".join(code)
-
-
-def generate_test(context):
+def generate_test(context, metarig_type="", GENERATE_FINAL=True):
import os
new_objects = []
@@ -632,53 +321,58 @@ def generate_test(context):
obj_new.data = armature
scene.objects.link(obj_new)
scene.objects.active = obj_new
+ for obj in scene.objects:
+ obj.selected = False
+ obj_new.selected = True
- files = os.listdir(os.path.dirname(__file__))
- for f in files:
- if f.startswith("_"):
- continue
-
- if not f.endswith(".py"):
+ for module_name in submodule_types():
+ if (metarig_type and module_name != metarig_type):
continue
-
- module_name = f[:-3]
- submodule = __import__(name="%s.%s" % (__package__, module_name), fromlist=[module_name])
+
+ submodule, func = submodule_func_from_type(module_name)
metarig_template = getattr(submodule, "metarig_template", None)
if metarig_template:
create_empty_armature("meta_" + module_name) # sets active
metarig_template()
- obj = context.object
- obj_new = generate_rig(context, obj)
-
- new_objects.append((obj, obj_new))
+ obj = context.active_object
+ obj.location = scene.cursor_location
+
+ if GENERATE_FINAL:
+ obj_new = generate_rig(context, obj)
+ new_objects.append((obj, obj_new))
+ else:
+ new_objects.append((obj, None))
else:
print("note: rig type '%s' has no metarig_template(), can't test this", module_name)
return new_objects
-def generate_test_all(context):
+def generate_test_all(context, GRAPH=False):
import rigify
+ import rigify_utils
import graphviz_export
import os
reload(rigify)
+ reload(rigify_utils)
reload(graphviz_export)
new_objects = rigify.generate_test(context)
+
+ if GRAPH:
+ base_name = os.path.splitext(bpy.data.filename)[0]
+ for obj, obj_new in new_objects:
+ for obj in (obj, obj_new):
+ fn = base_name + "-" + bpy.utils.clean_name(obj.name)
- base_name = os.path.splitext(bpy.data.filename)[0]
- for obj, obj_new in new_objects:
- for obj in (obj, obj_new):
- fn = base_name + "-" + bpy.utils.clean_name(obj.name)
-
- path_dot = fn + ".dot"
- path_png = fn + ".png"
- saved = graphviz_export.graph_armature(obj, path_dot, CONSTRAINTS=True, DRIVERS=True)
+ path_dot = fn + ".dot"
+ path_png = fn + ".png"
+ saved = graphviz_export.graph_armature(obj, path_dot, CONSTRAINTS=True, DRIVERS=True)
- #if saved:
- # os.system("dot -Tpng %s > %s; eog %s" % (path_dot, path_png, path_png))
+ #if saved:
+ # os.system("dot -Tpng %s > %s; eog %s" % (path_dot, path_png, path_png))
i = 0
for obj, obj_new in new_objects:
@@ -691,4 +385,4 @@ def generate_test_all(context):
if __name__ == "__main__":
- generate_rig(bpy.context, bpy.context.object)
+ generate_rig(bpy.context, bpy.context.active_object)
diff --git a/release/scripts/modules/rigify/arm.py b/release/scripts/modules/rigify/arm_biped_generic.py
index 6ed564ac070..e22857852ee 100644
--- a/release/scripts/modules/rigify/arm.py
+++ b/release/scripts/modules/rigify/arm_biped_generic.py
@@ -19,7 +19,8 @@
# <pep8 compliant>
import bpy
-from rigify import bone_class_instance, copy_bone_simple, add_pole_target_bone, add_stretch_to, blend_bone_list
+from rigify import RigifyError
+from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone, add_stretch_to, blend_bone_list, get_side_name, get_base_name
from rna_prop_ui import rna_idprop_ui_prop_get
from Mathutils import Vector
@@ -29,7 +30,7 @@ METARIG_NAMES = "shoulder", "arm", "forearm", "hand"
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')
- obj = bpy.context.object
+ obj = bpy.context.active_object
arm = obj.data
bone = arm.edit_bones.new('shoulder')
bone.head[:] = 0.0000, -0.4515, 0.0000
@@ -57,7 +58,7 @@ def metarig_template():
bpy.ops.object.mode_set(mode='OBJECT')
pbone = obj.pose.bones['upper_arm']
- pbone['type'] = 'arm'
+ pbone['type'] = 'arm_biped_generic'
def metarig_definition(obj, orig_bone_name):
@@ -68,10 +69,7 @@ def metarig_definition(obj, orig_bone_name):
mt.shoulder_p = mt.arm_p.parent
if not mt.shoulder_p:
- raise Exception("could not find '%s' parent, skipping:" % orig_bone_name)
-
- if mt.arm_p.parent.bone.connected:
- raise Exception("expected '%s' to be disconnected from its parent" % orig_bone_name)
+ raise RigifyError("could not find '%s' parent, skipping:" % orig_bone_name)
mt.shoulder = mt.shoulder_p.name
@@ -79,11 +77,11 @@ def metarig_definition(obj, orig_bone_name):
hands = []
for pbone in obj.pose.bones:
index = pbone.parent_index(mt.arm_p)
- if index == 2:
+ if index == 2 and pbone.bone.connected and pbone.bone.parent.connected:
hands.append(pbone)
if len(hands) != 1:
- raise Exception("Expected more then 1 hand found on:", orig_bone_name)
+ raise RigifyError("Found %s possible hands attached to this arm, expected 1 from bone: %s" % ([pbone.name for pbone in hands], orig_bone_name))
# first add the 2 new bones
mt.hand_p = hands[0]
@@ -106,12 +104,18 @@ def ik(obj, definitions, base_names):
# IK needs no parent_index
ik_chain.hand_e.connected = False
ik_chain.hand_e.parent = None
+ ik_chain.hand_e.local_location = False
+ ik_chain.rename("hand", get_base_name(base_names[mt.hand]) + "_ik" + get_side_name(mt.hand))
ik_chain.arm_e.connected = False
ik_chain.arm_e.parent = mt.shoulder_e
# Add the bone used for the arms poll target
- ik.pole = add_pole_target_bone(obj, mt.forearm, "elbow_poll", mode='ZAVERAGE')
+ #ik.pole = add_pole_target_bone(obj, mt.forearm, get_base_name(base_names[mt.forearm]) + "_target" + get_side_name(mt.forearm), mode='ZAVERAGE')
+ ik.pole = add_pole_target_bone(obj, mt.forearm, "elbow_target" + get_side_name(mt.forearm), mode='ZAVERAGE')
+
+ ik.update()
+ ik.pole_e.local_location = False
# update bones after this!
ik.hand_vis = add_stretch_to(obj, mt.hand, ik_chain.hand, "VIS-%s_ik" % base_names[mt.hand])
@@ -178,7 +182,7 @@ def fk(obj, definitions, base_names):
ex.socket = ex.socket_e.name
ex.socket_e.connected = False
ex.socket_e.parent = mt.shoulder_e
- ex.socket_e.tail = mt.shoulder_e.tail
+ ex.socket_e.length *= 0.5
# insert the 'DLT-hand', between the forearm and the hand
# copies forarm rotation
@@ -236,7 +240,7 @@ def fk(obj, definitions, base_names):
tar.name = "hinge"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = controller_path + '["hinge"]'
+ tar.data_path = controller_path + '["hinge"]'
mod = driver_fcurve.modifiers[0]
mod.poly_order = 1
diff --git a/release/scripts/modules/rigify/copy.py b/release/scripts/modules/rigify/copy.py
new file mode 100644
index 00000000000..21d0970234b
--- /dev/null
+++ b/release/scripts/modules/rigify/copy.py
@@ -0,0 +1,66 @@
+# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+from rigify_utils import copy_bone_simple, get_side_name, bone_class_instance
+from rna_prop_ui import rna_idprop_ui_prop_get
+
+METARIG_NAMES = ("cpy",)
+
+# note, this example is just a bone with copy property.
+def metarig_template():
+ # generated by rigify.write_meta_rig
+ bpy.ops.object.mode_set(mode='EDIT')
+ obj = bpy.context.active_object
+ arm = obj.data
+ bone = arm.edit_bones.new('Bone')
+ bone.head[:] = 0.0000, 0.0000, 0.0000
+ bone.tail[:] = 0.0000, 0.0000, 1.0000
+ bone.roll = 0.0000
+ bone.connected = False
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones['Bone']
+ pbone['type'] = 'copy'
+
+def metarig_definition(obj, orig_bone_name):
+ return [orig_bone_name]
+
+
+def main(obj, bone_definition, base_names):
+ arm = obj.data
+ mt = bone_class_instance(obj, METARIG_NAMES)
+ mt.cpy = bone_definition[0]
+ mt.update()
+ cp = mt.copy(to_fmt="%s_cpy")
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ cp.update()
+ mt.update()
+
+ con = cp.cpy_p.constraints.new('COPY_ROTATION')
+ con.target = obj
+ con.subtarget = mt.cpy
+
+ con = cp.cpy_p.constraints.new('COPY_LOCATION')
+ con.target = obj
+ con.subtarget = mt.cpy
+
+ return [mt.cpy]
diff --git a/release/scripts/modules/rigify/delta.py b/release/scripts/modules/rigify/delta.py
index 00d79ed33df..261e2b22479 100644
--- a/release/scripts/modules/rigify/delta.py
+++ b/release/scripts/modules/rigify/delta.py
@@ -19,12 +19,40 @@
# <pep8 compliant>
import bpy
-from rigify import get_bone_data
+from rigify import RigifyError
# not used, defined for completeness
METARIG_NAMES = tuple()
+def metarig_template():
+ # generated by rigify.write_meta_rig
+ bpy.ops.object.mode_set(mode='EDIT')
+ obj = bpy.context.active_object
+ arm = obj.data
+ bone = arm.edit_bones.new('bonesker')
+ bone.head[:] = 0.0000, 0.0000, 0.0000
+ bone.tail[:] = -0.0000, 0.7382, 0.1895
+ bone.roll = -0.0000
+ bone.connected = False
+ bone = arm.edit_bones.new('delta')
+ bone.head[:] = -0.0497, 0.8414, 0.3530
+ bone.tail[:] = -0.2511, 1.1588, 0.9653
+ bone.roll = 2.6044
+ bone.connected = False
+ bone.parent = arm.edit_bones['bonesker']
+ bone = arm.edit_bones.new('boney')
+ bone.head[:] = 0.7940, 2.5592, 0.4134
+ bone.tail[:] = 0.7940, 3.3975, 0.4890
+ bone.roll = 3.1416
+ bone.connected = False
+ bone.parent = arm.edit_bones['delta']
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones['delta']
+ pbone['type'] = 'delta'
+
+
def metarig_definition(obj, orig_bone_name):
'''
The bone given is the head, its parent is the body,
@@ -37,7 +65,10 @@ def metarig_definition(obj, orig_bone_name):
children = delta.children
if len(children) != 1:
- print("only 1 child supported for delta")
+ raise RigifyError("only 1 child supported for delta on bone '%s'" % delta.name)
+
+ if delta.connected:
+ raise RigifyError("bone cannot be connected to its parent '%s'" % delta.name)
bone_definition = [delta.name, children[0].name]
@@ -48,7 +79,6 @@ def main(obj, bone_definition, base_names):
'''
Use this bone to define a delta thats applied to its child in pose mode.
'''
-
mode_orig = obj.mode
bpy.ops.object.mode_set(mode='OBJECT')
@@ -56,7 +86,8 @@ def main(obj, bone_definition, base_names):
delta_pbone = obj.pose.bones[delta_name]
- arm, child_pbone, child_bone = get_bone_data(obj, child_name)
+ arm = obj.data
+ child_pbone = obj.pose.bones[child_name]
delta_phead = delta_pbone.head.copy()
delta_ptail = delta_pbone.tail.copy()
@@ -77,7 +108,6 @@ def main(obj, bone_definition, base_names):
delta_head = delta_ebone.head.copy()
delta_tail = delta_ebone.tail.copy()
- # arm, parent_pbone, parent_bone = get_bone_data(obj, delta_name)
child_head = child_ebone.head.copy()
child_tail = child_ebone.tail.copy()
@@ -125,7 +155,6 @@ def main(obj, bone_definition, base_names):
mod.coefficients[1] = 0.0
- # arm, parent_pbone, parent_bone = get_bone_data(obj, delta_name)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.mode_set(mode=mode_orig)
diff --git a/release/scripts/modules/rigify/finger.py b/release/scripts/modules/rigify/finger_curl.py
index baa9ed49041..7f21eecd7d3 100644
--- a/release/scripts/modules/rigify/finger.py
+++ b/release/scripts/modules/rigify/finger_curl.py
@@ -19,7 +19,8 @@
# <pep8 compliant>
import bpy
-from rigify import get_bone_data, empty_layer, copy_bone_simple
+from rigify import RigifyError
+from rigify_utils import copy_bone_simple, get_side_name, get_base_name, EMPTY_LAYER
from rna_prop_ui import rna_idprop_ui_prop_get
from functools import reduce
@@ -28,7 +29,7 @@ METARIG_NAMES = "finger_01", "finger_02", "finger_03"
def metarig_template():
bpy.ops.object.mode_set(mode='EDIT')
- obj = bpy.context.object
+ obj = bpy.context.active_object
arm = obj.data
bone = arm.edit_bones.new('finger.01')
bone.head[:] = 0.0000, 0.0000, 0.0000
@@ -50,7 +51,7 @@ def metarig_template():
bpy.ops.object.mode_set(mode='OBJECT')
pbone = obj.pose.bones['finger.01']
- pbone['type'] = 'finger'
+ pbone['type'] = 'finger_curl'
def metarig_definition(obj, orig_bone_name):
@@ -73,13 +74,13 @@ def metarig_definition(obj, orig_bone_name):
children = bone.children
if len(children) != 1:
- raise Exception("expected the chain to have 2 children without a fork")
+ raise RigifyError("expected the chain to have 2 children from bone '%s' without a fork" % orig_bone_name)
bone = children[0]
bone_definition.append(bone.name) # finger_02, finger_03
chain += 1
if len(bone_definition) != len(METARIG_NAMES):
- raise Exception("internal problem, expected %d bones" % len(METARIG_NAMES))
+ raise RigifyError("internal problem, expected %d bones" % len(METARIG_NAMES))
return bone_definition
@@ -89,7 +90,9 @@ def main(obj, bone_definition, base_names):
# *** EDITMODE
# get assosiated data
- arm, orig_pbone, orig_ebone = get_bone_data(obj, bone_definition[0])
+ arm = obj.data
+ orig_pbone = obj.pose.bones[bone_definition[0]]
+ orig_ebone = arm.edit_bones[bone_definition[0]]
obj.animation_data_create() # needed if its a new armature with no keys
@@ -98,11 +101,12 @@ def main(obj, bone_definition, base_names):
children = orig_pbone.children_recursive
tot_len = reduce(lambda f, pbone: f + pbone.bone.length, children, orig_pbone.bone.length)
- base_name = base_names[bone_definition[0]].rsplit(".", 1)[0]
+ # FIXME, the line below is far too arbitrary
+ base_name = base_names[bone_definition[0]].rsplit(".", 2)[0]
# first make a new bone at the location of the finger
#control_ebone = arm.edit_bones.new(base_name)
- control_ebone = copy_bone_simple(arm, bone_definition[0], base_name)
+ control_ebone = copy_bone_simple(arm, bone_definition[0], base_name + get_side_name(base_names[bone_definition[0]]), parent=True)
control_bone_name = control_ebone.name # we dont know if we get the name requested
control_ebone.connected = orig_ebone.connected
@@ -115,7 +119,7 @@ def main(obj, bone_definition, base_names):
children = [pbone.name for pbone in children]
# set an alternate layer for driver bones
- other_layer = empty_layer[:]
+ other_layer = EMPTY_LAYER[:]
other_layer[8] = True
@@ -197,14 +201,14 @@ def main(obj, bone_definition, base_names):
tar.name = "scale"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = controller_path + '.scale[1]'
+ tar.data_path = controller_path + '.scale[1]'
# bend target
tar = driver.targets.new()
tar.name = "br"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = controller_path + '["bend_ratio"]'
+ tar.data_path = controller_path + '["bend_ratio"]'
# XXX - todo, any number
if i == 0:
diff --git a/release/scripts/modules/rigify/leg.py b/release/scripts/modules/rigify/leg_biped_generic.py
index ed28c21fd32..65fde79da6e 100644
--- a/release/scripts/modules/rigify/leg.py
+++ b/release/scripts/modules/rigify/leg_biped_generic.py
@@ -19,7 +19,8 @@
# <pep8 compliant>
import bpy
-from rigify import bone_class_instance, copy_bone_simple, blend_bone_list
+from rigify import RigifyError
+from rigify_utils import bone_class_instance, copy_bone_simple, blend_bone_list, get_side_name, get_base_name
from rna_prop_ui import rna_idprop_ui_prop_get
METARIG_NAMES = "hips", "thigh", "shin", "foot", "toe", "heel"
@@ -28,7 +29,7 @@ METARIG_NAMES = "hips", "thigh", "shin", "foot", "toe", "heel"
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')
- obj = bpy.context.object
+ obj = bpy.context.active_object
arm = obj.data
bone = arm.edit_bones.new('hips')
bone.head[:] = 0.0000, 0.0000, 0.0000
@@ -68,7 +69,7 @@ def metarig_template():
bpy.ops.object.mode_set(mode='OBJECT')
pbone = obj.pose.bones['thigh']
- pbone['type'] = 'leg'
+ pbone['type'] = 'leg_biped_generic'
def metarig_definition(obj, orig_bone_name):
@@ -85,7 +86,7 @@ def metarig_definition(obj, orig_bone_name):
orig_bone_parent = orig_bone.parent
if orig_bone_parent is None:
- raise Exception("expected the thigh bone to have a parent hip bone")
+ raise RigifyError("expected the thigh bone to have a parent hip bone")
bone_definition.append(orig_bone_parent.name)
bone_definition.append(orig_bone.name)
@@ -97,7 +98,7 @@ def metarig_definition(obj, orig_bone_name):
children = bone.children
if len(children) != 1:
- raise Exception("expected the thigh bone to have 3 children without a fork")
+ raise RigifyError("expected the thigh bone to have 3 children without a fork")
bone = children[0]
bone_definition.append(bone.name) # shin, foot
chain += 1
@@ -105,10 +106,10 @@ def metarig_definition(obj, orig_bone_name):
children = bone.children
# Now there must be 2 children, only one connected
if len(children) != 2:
- raise Exception("expected the foot bone:'%s' to have 2 children" % bone.name )
+ raise RigifyError("expected the foot bone:'%s' to have 2 children" % bone.name )
if children[0].connected == children[1].connected:
- raise Exception("expected one bone to be connected")
+ raise RigifyError("expected one bone to be connected")
toe, heel = children
if heel.connected:
@@ -119,7 +120,7 @@ def metarig_definition(obj, orig_bone_name):
bone_definition.append(heel.name)
if len(bone_definition) != len(METARIG_NAMES):
- raise Exception("internal problem, expected %d bones" % len(METARIG_NAMES))
+ raise RigifyError("internal problem, expected %d bones" % len(METARIG_NAMES))
return bone_definition
@@ -145,22 +146,26 @@ def ik(obj, bone_definition, base_names):
# XXX - end dupe
- # Make a new chain, ORG are the original bones renamed.
- ik_chain = mt_chain.copy(to_fmt="MCH-%s")
+ # Make a new chain
+ ik_chain = mt_chain.copy(to_fmt="MCH-%s", base_names=base_names)
# simple rename
ik_chain.rename("thigh", ik_chain.thigh + "_ik")
ik_chain.rename("shin", ik_chain.shin + "_ik")
- # ik foot, no parents
- base_foot_name = base_names[mt_chain.foot] # whatever the foot is called, use that!, XXX - ORG!
- ik.foot_e = copy_bone_simple(arm, mt_chain.foot, "%s_ik" % base_foot_name)
+ # make sure leg is child of hips
+ ik_chain.thigh_e.parent = mt.hips_e
+
+ # ik foot: no parents
+ base_foot_name = get_base_name(base_names[mt_chain.foot])
+ ik.foot_e = copy_bone_simple(arm, mt_chain.foot, base_foot_name + "_ik" + get_side_name(base_names[mt_chain.foot]))
ik.foot = ik.foot_e.name
ik.foot_e.tail.z = ik.foot_e.head.z
ik.foot_e.roll = 0.0
+ ik.foot_e.local_location = False
- # heel pointing backwards, half length
- ik.foot_roll_e = copy_bone_simple(arm, mt.heel, "%s_roll" % base_foot_name)
+ # foot roll: heel pointing backwards, half length
+ ik.foot_roll_e = copy_bone_simple(arm, mt.heel, base_foot_name + "_roll" + get_side_name(base_names[mt_chain.foot]))
ik.foot_roll = ik.foot_roll_e.name
ik.foot_roll_e.tail = ik.foot_roll_e.head + (ik.foot_roll_e.head - ik.foot_roll_e.tail) / 2.0
ik.foot_roll_e.parent = ik.foot_e # heel is disconnected
@@ -182,7 +187,7 @@ def ik(obj, bone_definition, base_names):
# rename 'MCH-toe' --> to 'toe_ik' and make the child of ik.foot_roll_01
# ------------------ FK or IK?
- ik_chain.rename("toe", base_names[mt_chain.toe] + "_ik")
+ ik_chain.rename("toe", get_base_name(base_names[mt_chain.toe]) + "_ik" + get_side_name(base_names[mt_chain.toe]))
ik_chain.toe_e.connected = False
ik_chain.toe_e.parent = ik.foot_roll_01_e
@@ -201,6 +206,7 @@ def ik(obj, bone_definition, base_names):
ik.knee_target_e.translate(offset)
ik.knee_target_e.length *= 0.5
ik.knee_target_e.parent = ik.foot_e
+ ik.knee_target_e.local_location = False
# roll the bone to point up... could also point in the same direction as ik.foot_roll
# ik.foot_roll_02_e.matrix * Vector(0.0, 0.0, 1.0) # ACK!, no rest matrix in editmode
@@ -218,6 +224,12 @@ def ik(obj, bone_definition, base_names):
ik_chain.shin_p.ik_dof_y = False
ik_chain.shin_p.ik_dof_z = False
+ # Set rotation modes and axis locks
+ ik.foot_roll_p.rotation_mode = 'XYZ'
+ ik.foot_roll_p.lock_rotation = False, True, True
+ ik_chain.toe_p.rotation_mode = 'YXZ'
+ ik_chain.toe_p.lock_rotation = False, True, True
+
# IK
con = ik_chain.shin_p.constraints.new('IK')
con.chain_length = 2
@@ -284,13 +296,10 @@ def fk(obj, bone_definition, base_names):
ex.thigh_socket = ex.thigh_socket_e.name
ex.thigh_socket_e.tail = ex.thigh_socket_e.head + Vector(0.0, 0.0, ex.thigh_socket_e.length / 4.0)
- ex.thigh_hinge_e = copy_bone_simple(arm, mt_chain.thigh, "MCH-%s_hinge" % base_names[mt_chain.thigh])
+ ex.thigh_hinge_e = copy_bone_simple(arm, mt.hips, "MCH-%s_hinge" % base_names[mt_chain.thigh], parent=False)
ex.thigh_hinge = ex.thigh_hinge_e.name
- ex.thigh_hinge_e.tail = ex.thigh_hinge_e.head + Vector(0.0, 0.0, mt_chain.thigh_e.head.length)
- ex.thigh_hinge_e.translate(Vector( - (mt.hips_e.head.x - mt_chain.thigh_e.head.x), 0.0, 0.0))
- ex.thigh_hinge_e.length = mt.hips_e.length
- fk_chain = mt_chain.copy() # fk has no prefix!
+ fk_chain = mt_chain.copy(base_names=base_names) # fk has no prefix!
fk_chain.thigh_e.connected = False
fk_chain.thigh_e.parent = ex.thigh_hinge_e
@@ -301,6 +310,13 @@ def fk(obj, bone_definition, base_names):
mt_chain.update()
fk_chain.update()
+ # Set rotation modes and axis locks
+ fk_chain.shin_p.rotation_mode = 'XYZ'
+ fk_chain.shin_p.lock_rotation = False, True, True
+ fk_chain.foot_p.rotation_mode = 'YXZ'
+ fk_chain.toe_p.rotation_mode = 'YXZ'
+ fk_chain.toe_p.lock_rotation = False, True, True
+
con = fk_chain.thigh_p.constraints.new('COPY_LOCATION')
con.target = obj
con.subtarget = ex.thigh_socket
@@ -325,7 +341,7 @@ def fk(obj, bone_definition, base_names):
tar.name = "var"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = hinge_driver_path
+ tar.data_path = hinge_driver_path
mod = fcurve.modifiers[0]
mod.poly_order = 1
diff --git a/release/scripts/modules/rigify/neck.py b/release/scripts/modules/rigify/neck_flex.py
index 887b0b091fc..9bb852b25b5 100644
--- a/release/scripts/modules/rigify/neck.py
+++ b/release/scripts/modules/rigify/neck_flex.py
@@ -19,7 +19,8 @@
# <pep8 compliant>
import bpy
-from rigify import bone_class_instance, copy_bone_simple
+from rigify import RigifyError
+from rigify_utils import bone_class_instance, copy_bone_simple
from rna_prop_ui import rna_idprop_ui_prop_get
# not used, defined for completeness
@@ -29,7 +30,7 @@ METARIG_NAMES = ("body", "head")
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')
- obj = bpy.context.object
+ obj = bpy.context.active_object
arm = obj.data
bone = arm.edit_bones.new('body')
bone.head[:] = -0.0000, -0.2771, -1.3345
@@ -75,7 +76,7 @@ def metarig_template():
bpy.ops.object.mode_set(mode='OBJECT')
pbone = obj.pose.bones['head']
- pbone['type'] = 'neck'
+ pbone['type'] = 'neck_flex'
def metarig_definition(obj, orig_bone_name):
@@ -91,7 +92,7 @@ def metarig_definition(obj, orig_bone_name):
children = head.children
if len(children) != 1:
- print("expected the head to have only 1 child.")
+ raise RigifyError("expected the head bone '%s' to have only 1 child." % orig_bone_name)
child = children[0]
bone_definition = [body.name, head.name, child.name]
@@ -120,10 +121,14 @@ def main(obj, bone_definition, base_names):
neck_chain_basename = base_names[mt_chain.neck_01_e.name].split(".")[0]
neck_chain_segment_length = mt_chain.neck_01_e.length
- ex = bone_class_instance(obj, ["body", "head", "head_hinge", "neck_socket"]) # hinge & extras
+ ex = bone_class_instance(obj, ["body", "head", "head_hinge", "neck_socket", "head_ctrl"]) # hinge & extras
# Add the head hinge at the bodys location, becomes the parent of the original head
+ # apply everything to this copy of the chain
+ ex_chain = mt_chain.copy(base_names=base_names)
+ ex_chain.neck_01_e.parent = mt_chain.neck_01_e.parent
+
# Copy the head bone and offset
ex.head_e = copy_bone_simple(arm, mt.head, "MCH_%s" % base_names[mt.head], parent=True)
@@ -135,16 +140,12 @@ def main(obj, bone_definition, base_names):
ex.head_e.tail.y += head_length / 2.0
# Yes, use the body bone but call it a head hinge
- ex.head_hinge_e = copy_bone_simple(arm, mt.body, "MCH_%s_hinge" % base_names[mt.head], parent=True)
+ ex.head_hinge_e = copy_bone_simple(arm, mt.body, "MCH_%s_hinge" % base_names[mt.head], parent=False)
ex.head_hinge_e.connected = False
ex.head_hinge = ex.head_hinge_e.name
ex.head_hinge_e.head.y += head_length / 4.0
ex.head_hinge_e.tail.y += head_length / 4.0
- # reparent the head, assume its not connected
- mt.head_e.connected = False
- mt.head_e.parent = ex.head_hinge_e
-
# Insert the neck socket, the head copys this loation
ex.neck_socket_e = arm.edit_bones.new("MCH-%s_socked" % neck_chain_basename)
ex.neck_socket = ex.neck_socket_e.name
@@ -153,20 +154,21 @@ def main(obj, bone_definition, base_names):
ex.neck_socket_e.head = mt.head_e.head
ex.neck_socket_e.tail = mt.head_e.head - Vector(0.0, neck_chain_segment_length / 2.0, 0.0)
ex.neck_socket_e.roll = 0.0
+
+
+ # copy of the head for controling
+ ex.head_ctrl_e = copy_bone_simple(arm, mt.head, base_names[mt.head])
+ ex.head_ctrl = ex.head_ctrl_e.name
+ ex.head_ctrl_e.parent = ex.head_hinge_e
- # offset the head, not really needed since it has a copyloc constraint
- mt.head_e.head.y += head_length / 4.0
- mt.head_e.tail.y += head_length / 4.0
-
- for i, attr in enumerate(mt_chain.attr_names):
- neck_e = getattr(mt_chain, attr + "_e")
+ for i, attr in enumerate(ex_chain.attr_names):
+ neck_e = getattr(ex_chain, attr + "_e")
# dont store parent names, re-reference as each chain bones parent.
- neck_e_parent = arm.edit_bones.new("MCH-rot_%s" % base_names[neck_e.name])
+ neck_e_parent = arm.edit_bones.new("MCH-rot_%s" % base_names[getattr(mt_chain, attr)])
neck_e_parent.head = neck_e.head
neck_e_parent.tail = neck_e.head + ((mt.head_e.tail - mt.head_e.head).normalize() * neck_chain_segment_length / 2.0)
neck_e_parent.roll = mt.head_e.roll
-
orig_parent = neck_e.parent
neck_e.connected = False
@@ -183,20 +185,21 @@ def main(obj, bone_definition, base_names):
mt.update()
mt_chain.update()
+ ex_chain.update()
ex.update()
# Simple one off constraints, no drivers
- con = mt.head_p.constraints.new('COPY_LOCATION')
+ con = ex.head_ctrl_p.constraints.new('COPY_LOCATION')
con.target = obj
con.subtarget = ex.neck_socket
con = ex.head_p.constraints.new('COPY_ROTATION')
con.target = obj
- con.subtarget = mt.head
+ con.subtarget = ex.head_ctrl
# driven hinge
- prop = rna_idprop_ui_prop_get(mt.head_p, "hinge", create=True)
- mt.head_p["hinge"] = 0.0
+ prop = rna_idprop_ui_prop_get(ex.head_ctrl_p, "hinge", create=True)
+ ex.head_ctrl_p["hinge"] = 0.0
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
@@ -206,7 +209,7 @@ def main(obj, bone_definition, base_names):
con.subtarget = mt.body
# add driver
- hinge_driver_path = mt.head_p.path_to_id() + '["hinge"]'
+ hinge_driver_path = ex.head_ctrl_p.path_to_id() + '["hinge"]'
fcurve = con.driver_add("influence", 0)
driver = fcurve.driver
@@ -215,7 +218,7 @@ def main(obj, bone_definition, base_names):
tar.name = "var"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = hinge_driver_path
+ tar.data_path = hinge_driver_path
#mod = fcurve_driver.modifiers.new('GENERATOR')
mod = fcurve.modifiers[0]
@@ -223,12 +226,12 @@ def main(obj, bone_definition, base_names):
mod.coefficients[0] = 1.0
mod.coefficients[1] = -1.0
- head_driver_path = mt.head_p.path_to_id()
+ head_driver_path = ex.head_ctrl_p.path_to_id()
target_names = [("b%.2d" % (i + 1)) for i in range(len(neck_chain))]
- mt.head_p["bend_tot"] = 0.0
- fcurve = mt.head_p.driver_add('["bend_tot"]', 0)
+ ex.head_ctrl_p["bend_tot"] = 0.0
+ fcurve = ex.head_ctrl_p.driver_add('["bend_tot"]', 0)
driver = fcurve.driver
driver.type = 'SUM'
fcurve.modifiers.remove(0) # grr dont need a modifier
@@ -238,19 +241,19 @@ def main(obj, bone_definition, base_names):
tar.name = target_names[i]
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = head_driver_path + ('["bend_%.2d"]' % (i + 1))
+ tar.data_path = head_driver_path + ('["bend_%.2d"]' % (i + 1))
- for i, attr in enumerate(mt_chain.attr_names):
- neck_p = getattr(mt_chain, attr + "_p")
+ for i, attr in enumerate(ex_chain.attr_names):
+ neck_p = getattr(ex_chain, attr + "_p")
neck_p.lock_location = True, True, True
neck_p.lock_location = True, True, True
neck_p.lock_rotations_4d = True
# Add bend prop
prop_name = "bend_%.2d" % (i + 1)
- prop = rna_idprop_ui_prop_get(mt.head_p, prop_name, create=True)
- mt.head_p[prop_name] = 1.0
+ prop = rna_idprop_ui_prop_get(ex.head_ctrl_p, prop_name, create=True)
+ ex.head_ctrl_p[prop_name] = 1.0
prop["soft_min"] = 0.0
prop["soft_max"] = 1.0
@@ -278,13 +281,20 @@ def main(obj, bone_definition, base_names):
tar.name = "bend_tot"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = head_driver_path + ('["bend_tot"]')
+ tar.data_path = head_driver_path + ('["bend_tot"]')
tar = driver.targets.new()
tar.name = "bend"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = head_driver_path + ('["%s"]' % prop_name)
+ tar.data_path = head_driver_path + ('["%s"]' % prop_name)
+
+
+ # finally constrain the original bone to this one
+ orig_neck_p = getattr(mt_chain, attr + "_p")
+ con = orig_neck_p.constraints.new('COPY_ROTATION')
+ con.target = obj
+ con.subtarget = neck_p.name
# no blending the result of this
return None
diff --git a/release/scripts/modules/rigify/palm.py b/release/scripts/modules/rigify/palm_curl.py
index 5f4ada6128d..867889b0084 100644
--- a/release/scripts/modules/rigify/palm.py
+++ b/release/scripts/modules/rigify/palm_curl.py
@@ -19,7 +19,7 @@
# <pep8 compliant>
import bpy
-from rigify import get_bone_data, copy_bone_simple
+from rigify_utils import copy_bone_simple, get_side_name
from rna_prop_ui import rna_idprop_ui_prop_get
# not used, defined for completeness
@@ -28,7 +28,7 @@ METARIG_NAMES = tuple()
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')
- obj = bpy.context.object
+ obj = bpy.context.active_object
arm = obj.data
bone = arm.edit_bones.new('hand')
bone.head[:] = 0.0082, -1.2492, 0.0000
@@ -74,7 +74,7 @@ def metarig_template():
bpy.ops.object.mode_set(mode='OBJECT')
pbone = obj.pose.bones['palm.01']
- pbone['type'] = 'palm'
+ pbone['type'] = 'palm_curl'
def metarig_definition(obj, orig_bone_name):
@@ -97,7 +97,8 @@ def metarig_definition(obj, orig_bone_name):
def main(obj, bone_definition, base_names):
- arm, palm_pbone, palm_ebone = get_bone_data(obj, bone_definition[0])
+ arm = obj.data
+
children = bone_definition[1:]
# Make a copy of the pinky
@@ -105,7 +106,10 @@ def main(obj, bone_definition, base_names):
pinky_ebone = arm.edit_bones[children[0]]
ring_ebone = arm.edit_bones[children[1]]
- control_ebone = copy_bone_simple(arm, pinky_ebone.name, "palm_control", parent=True)
+ # FIXME, why split the second one?
+ base_name = base_names[pinky_ebone.name].rsplit('.', 2)[0]
+
+ control_ebone = copy_bone_simple(arm, pinky_ebone.name, base_name + get_side_name(base_names[pinky_ebone.name]), parent=True)
control_name = control_ebone.name
offset = (pinky_ebone.head - ring_ebone.head)
@@ -114,9 +118,9 @@ def main(obj, bone_definition, base_names):
bpy.ops.object.mode_set(mode='OBJECT')
-
- arm, control_pbone, control_ebone = get_bone_data(obj, control_name)
- arm, pinky_pbone, pinky_ebone = get_bone_data(obj, children[0])
+ arm = obj.data
+ control_pbone = obj.pose.bones[control_name]
+ pinky_pbone = obj.pose.bones[children[0]]
control_pbone.rotation_mode = 'YZX'
control_pbone.lock_rotation = False, True, True
@@ -141,7 +145,7 @@ def main(obj, bone_definition, base_names):
tar.name = "x"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = controller_path + ".rotation_euler[0]"
+ tar.data_path = controller_path + ".rotation_euler[0]"
# *****
@@ -152,23 +156,43 @@ def main(obj, bone_definition, base_names):
tar.name = "x"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = controller_path + ".rotation_euler[0]"
+ tar.data_path = controller_path + ".rotation_euler[0]"
# *****
driver = driver_fcurves[2].driver
driver.expression = "(1.0-cos(x))-s"
+
+ def x_direction():
+ # NOTE: the direction of the Z rotation depends on which side the palm is on.
+ # we could do a simple side-of-x test but better to work out the direction
+ # the hand is facing.
+ from Mathutils import Vector, AngleBetweenVecs
+ from math import degrees
+ child_pbone_01 = obj.pose.bones[children[0]]
+ child_pbone_02 = obj.pose.bones[children[1]]
+
+ rel_vec = child_pbone_01.head - child_pbone_02.head
+ x_vec = child_pbone_01.matrix.rotationPart() * Vector(1.0, 0.0, 0.0)
+ return degrees(AngleBetweenVecs(rel_vec, x_vec)) > 90.0
+
+ if x_direction(): # flip
+ driver.expression = "-(%s)" % driver.expression
+
+ for fcurve in driver_fcurves:
+ fcurve.modifiers.remove(0) # grr dont need a modifier
+
tar = driver.targets.new()
tar.name = "x"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = controller_path + ".rotation_euler[0]"
+ tar.data_path = controller_path + ".rotation_euler[0]"
tar = driver.targets.new()
tar.name = "s"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = controller_path + '["spread"]'
+ tar.data_path = controller_path + '["spread"]'
for i, child_name in enumerate(children):
diff --git a/release/scripts/modules/rigify/spine.py b/release/scripts/modules/rigify/spine_pivot_flex.py
index 2ccc10350b1..beeb5c68b7c 100644
--- a/release/scripts/modules/rigify/spine.py
+++ b/release/scripts/modules/rigify/spine_pivot_flex.py
@@ -19,7 +19,7 @@
# <pep8 compliant>
import bpy
-from rigify import bone_class_instance, copy_bone_simple
+from rigify_utils import bone_class_instance, copy_bone_simple
from rna_prop_ui import rna_idprop_ui_prop_get
# not used, defined for completeness
@@ -29,7 +29,7 @@ METARIG_NAMES = ("pelvis", "ribcage")
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')
- obj = bpy.context.object
+ obj = bpy.context.active_object
arm = obj.data
bone = arm.edit_bones.new('pelvis')
bone.head[:] = -0.0000, -0.2559, 0.8673
@@ -87,7 +87,7 @@ def metarig_template():
bpy.ops.object.mode_set(mode='OBJECT')
pbone = obj.pose.bones['rib_cage']
- pbone['type'] = 'spine.fk'
+ pbone['type'] = 'spine_pivot_flex'
def metarig_definition(obj, orig_bone_name):
@@ -104,11 +104,11 @@ def metarig_definition(obj, orig_bone_name):
pelvis = ribcage.parent
if pelvis is None:
- raise Exception("expected the ribcage bone:'%s' to have a parent (ribcage)." % ribcage.name)
+ raise RigifyError("expected the ribcage bone:'%s' to have a parent (ribcage)." % ribcage.name)
children = ribcage.children
if len(children) != 1:
- raise Exception("expected the ribcage to have only 1 child.")
+ raise RigifyError("expected the ribcage to have only 1 child.")
child = children[0]
@@ -148,6 +148,7 @@ def main(obj, bone_definition, base_names):
ex.pelvis_copy_e = copy_bone_simple(arm, mt.pelvis, base_names[mt.pelvis]) # no parent
ex.pelvis_copy = ex.pelvis_copy_e.name
+ ex.pelvis_copy_e.local_location = False
# copy the pelvis, offset to make MCH-spine_rotate and MCH-ribcage_hinge
ex.ribcage_hinge_e = copy_bone_simple(arm, mt.pelvis, "MCH-%s_hinge" % base_names[mt.ribcage])
@@ -321,7 +322,7 @@ def main(obj, bone_definition, base_names):
tar.name = "var"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = ex.ribcage_copy_p.path_to_id() + '["hinge"]'
+ tar.data_path = ex.ribcage_copy_p.path_to_id() + '["hinge"]'
mod = fcurve.modifiers[0]
mod.poly_order = 1
@@ -405,7 +406,7 @@ def main(obj, bone_definition, base_names):
tar.name = target_names[i]
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = rib_driver_path + ('["bend_%.2d"]' % (i + 1))
+ tar.data_path = rib_driver_path + ('["bend_%.2d"]' % (i + 1))
for i in range(1, spine_chain_len):
@@ -440,13 +441,13 @@ def main(obj, bone_definition, base_names):
tar.name = "bend_tot"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = rib_driver_path + ('["bend_tot"]')
+ tar.data_path = rib_driver_path + ('["bend_tot"]')
tar = driver.targets.new()
tar.name = "bend"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = rib_driver_path + ('["%s"]' % prop_name)
+ tar.data_path = rib_driver_path + ('["%s"]' % prop_name)
@@ -489,7 +490,7 @@ def main(obj, bone_definition, base_names):
tar.name = "var"
tar.id_type = 'OBJECT'
tar.id = obj
- tar.rna_path = rib_driver_path + '["pivot_slide"]'
+ tar.data_path = rib_driver_path + '["pivot_slide"]'
mod = fcurve.modifiers[0]
mod.poly_order = 1
diff --git a/release/scripts/modules/rigify_utils.py b/release/scripts/modules/rigify_utils.py
new file mode 100644
index 00000000000..a1fc54cb5bb
--- /dev/null
+++ b/release/scripts/modules/rigify_utils.py
@@ -0,0 +1,472 @@
+# ##### 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# rigify its self does not depend on this module, however some of the
+# rigify templates use these utility functions.
+#
+# So even though this can be for general purpose use, this module was created
+# for rigify so in some cases seemingly generic functions make assumptions
+# that a generic function would need to check for.
+
+import bpy
+from Mathutils import Vector
+from rna_prop_ui import rna_idprop_ui_prop_get
+
+DELIMITER = '-._'
+EMPTY_LAYER = [False] * 32
+
+def add_stretch_to(obj, from_name, to_name, name):
+ '''
+ Adds a bone that stretches from one to another
+ '''
+
+ mode_orig = obj.mode
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ arm = obj.data
+ stretch_ebone = arm.edit_bones.new(name)
+ stretch_name = stretch_ebone.name
+ del name
+
+ head = stretch_ebone.head = arm.edit_bones[from_name].head.copy()
+ #tail = stretch_ebone.tail = arm.edit_bones[to_name].head.copy()
+
+ # annoying exception for zero length bones, since its using stretch_to the rest pose doesnt really matter
+ #if (head - tail).length < 0.1:
+ if 1:
+ tail = stretch_ebone.tail = arm.edit_bones[from_name].tail.copy()
+
+
+ # Now for the constraint
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ stretch_pbone = obj.pose.bones[stretch_name]
+
+ con = stretch_pbone.constraints.new('COPY_LOCATION')
+ con.target = obj
+ con.subtarget = from_name
+
+ con = stretch_pbone.constraints.new('STRETCH_TO')
+ con.target = obj
+ con.subtarget = to_name
+ con.original_length = (head - tail).length
+ con.keep_axis = 'PLANE_X'
+ con.volume = 'NO_VOLUME'
+
+ bpy.ops.object.mode_set(mode=mode_orig)
+
+ return stretch_name
+
+
+def copy_bone_simple(arm, from_bone, name, parent=False):
+ ebone = arm.edit_bones[from_bone]
+ ebone_new = arm.edit_bones.new(name)
+
+ if parent:
+ ebone_new.connected = ebone.connected
+ ebone_new.parent = ebone.parent
+
+ ebone_new.head = ebone.head
+ ebone_new.tail = ebone.tail
+ ebone_new.roll = ebone.roll
+ return ebone_new
+
+
+def copy_bone_simple_list(arm, from_bones, to_bones, parent=False):
+
+ if len(from_bones) != len(to_bones):
+ raise Exception("bone list sizes must match")
+
+ copy_bones = [copy_bone_simple(arm, bone_name, to_bones[i], True) for i, bone_name in enumerate(from_bones)]
+
+ # now we need to re-parent
+ for ebone in copy_bones:
+ parent = ebone.parent
+ if parent:
+ try:
+ i = from_bones.index(parent.name)
+ except:
+ i = -1
+
+ if i == -1:
+ ebone.parent = None
+ else:
+ ebone.parent = copy_bones[i]
+
+ return copy_bones
+
+
+def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, target_prop="blend"):
+
+ if obj.mode == 'EDIT':
+ raise Exception("blending cant be called in editmode")
+
+ if len(apply_bones) != len(from_bones):
+ raise Exception("lists differ in length (from -> apply): \n\t%s\n\t%s" % (from_bones, apply_bones))
+ if len(apply_bones) != len(to_bones):
+ raise Exception("lists differ in length (to -> apply): \n\t%s\n\t%s" % (to_bones, apply_bones))
+
+ # setup the blend property
+ if target_bone is None:
+ target_bone = apply_bones[-1] # default to the last bone
+
+ prop_pbone = obj.pose.bones[target_bone]
+ if prop_pbone.get(target_bone, None) is None:
+ prop = rna_idprop_ui_prop_get(prop_pbone, target_prop, create=True)
+ prop_pbone[target_prop] = 0.5
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+
+ driver_path = prop_pbone.path_to_id() + ('["%s"]' % target_prop)
+
+ def blend_target(driver):
+ tar = driver.targets.new()
+ tar.name = target_bone
+ tar.id_type = 'OBJECT'
+ tar.id = obj
+ tar.data_path = driver_path
+
+ def blend_location(new_pbone, from_bone_name, to_bone_name):
+ con = new_pbone.constraints.new('COPY_LOCATION')
+ con.target = obj
+ con.subtarget = from_bone_name
+
+ con = new_pbone.constraints.new('COPY_LOCATION')
+ con.target = obj
+ con.subtarget = to_bone_name
+
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ fcurve.modifiers.remove(0) # grr dont need a modifier
+
+ blend_target(driver)
+
+ def blend_rotation(new_pbone, from_bone_name, to_bone_name):
+ con = new_pbone.constraints.new('COPY_ROTATION')
+ con.target = obj
+ con.subtarget = from_bone_name
+
+ con = new_pbone.constraints.new('COPY_ROTATION')
+ con.target = obj
+ con.subtarget = to_bone_name
+
+ fcurve = con.driver_add("influence", 0)
+ driver = fcurve.driver
+ driver.type = 'AVERAGE'
+ fcurve.modifiers.remove(0) # grr dont need a modifier
+
+ blend_target(driver)
+
+ for i, new_bone_name in enumerate(apply_bones):
+ from_bone_name = from_bones[i]
+ to_bone_name = to_bones[i]
+
+ # allow skipping some bones by having None in the list
+ if None in (new_bone_name, from_bone_name, to_bone_name):
+ continue
+
+ new_pbone = obj.pose.bones[new_bone_name]
+
+ # if the bone is connected or its location is totally locked then dont add location blending.
+ if not (new_pbone.bone.connected or (False not in new_pbone.lock_location)):
+ blend_location(new_pbone, from_bone_name, to_bone_name)
+
+ if not (False not in new_pbone.lock_rotation): # TODO. 4D chech?
+ blend_rotation(new_pbone, from_bone_name, to_bone_name)
+
+
+def add_pole_target_bone(obj, base_bone_name, name, mode='CROSS'):
+ '''
+ Does not actually create a poll target, just the bone to use as a poll target
+ '''
+ mode_orig = obj.mode
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ arm = obj.data
+
+ poll_ebone = arm.edit_bones.new(name)
+ base_ebone = arm.edit_bones[base_bone_name]
+ poll_name = poll_ebone.name
+ parent_ebone = base_ebone.parent
+
+ base_head = base_ebone.head.copy()
+ base_tail = base_ebone.tail.copy()
+ base_dir = base_head - base_tail
+
+ parent_head = parent_ebone.head.copy()
+ parent_tail = parent_ebone.tail.copy()
+ parent_dir = parent_head - parent_tail
+
+ distance = (base_dir.length + parent_dir.length)
+
+ if mode == 'CROSS':
+ # direction from the angle of the joint
+ offset = base_dir.copy().normalize() - parent_dir.copy().normalize()
+ offset.length = distance
+ elif mode == 'ZAVERAGE':
+ # between both bones Z axis
+ z_axis_a = base_ebone.matrix.copy().rotationPart() * Vector(0.0, 0.0, -1.0)
+ z_axis_b = parent_ebone.matrix.copy().rotationPart() * Vector(0.0, 0.0, -1.0)
+ offset = (z_axis_a + z_axis_b).normalize() * distance
+ else:
+ # preset axis
+ offset = Vector(0, 0, 0)
+ if mode[0] == "+":
+ val = distance
+ else:
+ val = - distance
+
+ setattr(offset, mode[1].lower(), val)
+
+ poll_ebone.head = base_head + offset
+ poll_ebone.tail = base_head + (offset * (1.0 - (1.0 / 4.0)))
+
+ bpy.ops.object.mode_set(mode=mode_orig)
+
+ return poll_name
+
+
+
+def get_side_name(name):
+ '''
+ Returns the last part of a string (typically a bone's name) indicating
+ whether it is a a left or right (or center, or whatever) bone.
+ Returns an empty string if nothing is found.
+ '''
+ if name[-2] in DELIMITER:
+ return name[-2:]
+ else:
+ return ""
+
+def get_base_name(name):
+ '''
+ Returns the part of a string (typically a bone's name) corresponding to it's
+ base name (no sidedness, no ORG prefix).
+ '''
+ if name[-2] in DELIMITER:
+ return name[:-2]
+ else:
+ return name
+
+
+def write_meta_rig(obj, func_name="metarig_template"):
+ '''
+ Write a metarig as a python script, this rig is to have all info needed for
+ generating the real rig with rigify.
+ '''
+ code = []
+
+ code.append("def %s():" % func_name)
+ code.append(" # generated by rigify.write_meta_rig")
+ bpy.ops.object.mode_set(mode='EDIT')
+ code.append(" bpy.ops.object.mode_set(mode='EDIT')")
+
+ code.append(" obj = bpy.context.active_object")
+ code.append(" arm = obj.data")
+
+ arm = obj.data
+ # write parents first
+ bones = [(len(bone.parent_recursive), bone.name) for bone in arm.edit_bones]
+ bones.sort(key=lambda item: item[0])
+ bones = [item[1] for item in bones]
+
+
+ for bone_name in bones:
+ bone = arm.edit_bones[bone_name]
+ code.append(" bone = arm.edit_bones.new('%s')" % bone.name)
+ code.append(" bone.head[:] = %.4f, %.4f, %.4f" % bone.head.toTuple(4))
+ code.append(" bone.tail[:] = %.4f, %.4f, %.4f" % bone.tail.toTuple(4))
+ code.append(" bone.roll = %.4f" % bone.roll)
+ code.append(" bone.connected = %s" % str(bone.connected))
+ if bone.parent:
+ code.append(" bone.parent = arm.edit_bones['%s']" % bone.parent.name)
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ code.append("")
+ code.append(" bpy.ops.object.mode_set(mode='OBJECT')")
+
+ for bone_name in bones:
+ pbone = obj.pose.bones[bone_name]
+ pbone_written = False
+
+ # Only 1 level of props, simple types supported
+ for key, value in pbone.items():
+ if key.startswith("_"):
+ continue
+
+ if type(value) not in (float, str, int):
+ print("Unsupported ID Prop:", str((key, value)))
+ continue
+
+ if type(value) == str:
+ value = "'" + value + "'"
+
+ if not pbone_written: # only write bones we need
+ code.append(" pbone = obj.pose.bones['%s']" % bone_name)
+
+ code.append(" pbone['%s'] = %s" % (key, value))
+
+ return "\n".join(code)
+
+
+
+# *** bone class collection ***
+def bone_class_instance(obj, slots, name="BoneContainer"):
+ '''
+ bone collection utility class to help manage cases with
+ edit/pose/bone bones where switching modes can invalidate some of the members.
+
+ there are also utility functions for manipulating all members.
+ '''
+
+ if len(slots) != len(set(slots)):
+ raise Exception("duplicate entries found %s" % attr_names)
+
+ attr_names = tuple(slots) # dont modify the original
+ slots = list(slots) # dont modify the original
+ for i in range(len(slots)):
+ member = slots[i]
+ slots.append(member + "_b") # bone bone
+ slots.append(member + "_p") # pose bone
+ slots.append(member + "_e") # edit bone
+
+ class_dict = { \
+ "obj": obj, \
+ "attr_names": attr_names, \
+ "update": _bone_class_instance_update, \
+ "rename": _bone_class_instance_rename, \
+ "names": _bone_class_instance_names, \
+ "copy": _bone_class_instance_copy, \
+ "blend": _bone_class_instance_blend, \
+ }
+
+ instance = auto_class_instance(slots, name, class_dict)
+ return instance
+
+def auto_class(slots, name="ContainerClass", class_dict=None):
+
+ if class_dict:
+ class_dict = class_dict.copy()
+ else:
+ class_dict = {}
+
+ class_dict["__slots__"] = tuple(slots)
+
+ return type(name, (object,), class_dict)
+
+
+def auto_class_instance(slots, name="ContainerClass", class_dict=None):
+ return auto_class(slots, name, class_dict)()
+
+
+def _bone_class_instance_update(self):
+ ''' Re-Assigns bones from the blender data
+ '''
+ arm = self.obj.data
+ bbones = arm.bones
+ pbones = self.obj.pose.bones
+ ebones = arm.edit_bones
+
+ for member in self.attr_names:
+ name = getattr(self, member, None)
+ if name is not None:
+ setattr(self, member + "_b", bbones.get(name, None))
+ setattr(self, member + "_p", pbones.get(name, None))
+ setattr(self, member + "_e", ebones.get(name, None))
+
+
+def _bone_class_instance_rename(self, attr, new_name):
+ ''' Rename bones, editmode only
+ '''
+
+ if self.obj.mode != 'EDIT':
+ raise Exception("Only rename in editmode supported")
+
+ ebone = getattr(self, attr + "_e")
+ ebone.name = new_name
+
+ # we may not get what is asked for so get the name from the editbone
+ setattr(self, attr, ebone.name)
+
+
+def _bone_class_instance_copy(self, from_fmt="%s", to_fmt="%s", exclude_attrs=(), base_names=None):
+ from_name_ls = []
+ new_name_ls = []
+ new_slot_ls = []
+
+ for attr in self.attr_names:
+
+ if attr in exclude_attrs:
+ continue
+
+ bone_name_orig = getattr(self, attr)
+ ebone = getattr(self, attr + "_e")
+ # orig_names[attr] = bone_name_orig
+
+ # insert formatting
+ if from_fmt != "%s":
+ bone_name = from_fmt % bone_name_orig
+ ebone.name = bone_name
+ bone_name = ebone.name # cant be sure we get what we ask for
+ else:
+ bone_name = bone_name_orig
+
+ setattr(self, attr, bone_name)
+
+ new_slot_ls.append(attr)
+ from_name_ls.append(bone_name)
+ if base_names:
+ bone_name_orig = base_names[bone_name_orig]
+ new_name_ls.append(to_fmt % bone_name_orig)
+
+ new_bones = copy_bone_simple_list(self.obj.data, from_name_ls, new_name_ls, True)
+ new_bc = bone_class_instance(self.obj, new_slot_ls)
+
+ for i, attr in enumerate(new_slot_ls):
+ ebone = new_bones[i]
+ setattr(new_bc, attr + "_e", ebone)
+ setattr(new_bc, attr, ebone.name)
+
+ return new_bc
+
+
+def _bone_class_instance_names(self):
+ return [getattr(self, attr) for attr in self.attr_names]
+
+
+def _bone_class_instance_blend(self, from_bc, to_bc, target_bone=None, target_prop="blend"):
+ '''
+ Use for blending bone chains.
+
+ blend_target = (bone_name, bone_property)
+ default to the last bone, blend prop
+
+ XXX - toggles editmode, need to re-validate all editbones :(
+ '''
+
+ if self.attr_names != from_bc.attr_names or self.attr_names != to_bc.attr_names:
+ raise Exception("can only blend between matching chains")
+
+ apply_bones = [getattr(self, attr) for attr in self.attr_names]
+ from_bones = [getattr(from_bc, attr) for attr in from_bc.attr_names]
+ to_bones = [getattr(to_bc, attr) for attr in to_bc.attr_names]
+
+ blend_bone_list(self.obj, apply_bones, from_bones, to_bones, target_bone, target_prop)
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index dd71da74d35..07b3a7c1c42 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -120,7 +120,7 @@ def draw(layout, context, context_member, use_edit=True):
prop = row.operator("wm.properties_edit", text="edit")
assign_props(prop, val_draw, key)
- prop = row.operator("wm.properties_remove", text="", icon='ICON_ZOOMOUT')
+ prop = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')
assign_props(prop, val_draw, key)
diff --git a/release/scripts/op/add_mesh_torus.py b/release/scripts/op/add_mesh_torus.py
index fe8feecf43d..7e3b28b628e 100644
--- a/release/scripts/op/add_mesh_torus.py
+++ b/release/scripts/op/add_mesh_torus.py
@@ -131,7 +131,7 @@ bpy.ops.add(AddTorus)
import dynamic_menu
menu_func = (lambda self, context: self.layout.operator(AddTorus.bl_idname,
- text="Torus", icon='ICON_MESH_DONUT'))
+ text="Torus", icon='MESH_DONUT'))
menu_item = dynamic_menu.add(bpy.types.INFO_MT_mesh_add, menu_func)
diff --git a/release/scripts/op/screen_play_rendered_anim.py b/release/scripts/op/screen_play_rendered_anim.py
new file mode 100644
index 00000000000..e98fa45cbaa
--- /dev/null
+++ b/release/scripts/op/screen_play_rendered_anim.py
@@ -0,0 +1,99 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Script copyright (C) Campbell J Barton
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+# History
+#
+# Originally written by Matt Ebb
+
+import bpy
+import subprocess, platform
+
+# from BKE_add_image_extension()
+img_format_exts = {
+ 'IRIS':'.rgb',
+ 'RADHDR':'.hdr',
+ 'PNG':'png',
+ 'TARGA':'tga',
+ 'RAWTARGA':'tga',
+ 'BMP':'bmp',
+ 'TIFF':'tif',
+ 'OPENEXR':'exr',
+ 'MULTILAYER':'exr',
+ 'CINEON':'cin',
+ 'DPX':'dpx',
+ 'JPEG':'jpg',
+ 'JPEG2000':'jp2',
+ 'QUICKTIME_QTKIT':'mov',
+ 'QUICKTIME_CARBON':'mov',
+ 'AVIRAW':'avi',
+ 'AVIJPEG':'avi',
+ 'AVICODEC':'avi',
+ 'XVID':'avi',
+ 'THEORA':'ogg',
+ }
+
+class PlayRenderedAnim(bpy.types.Operator):
+
+ bl_idname = "screen.play_rendered_anim"
+ bl_label = "Play Rendered Animation"
+ bl_register = True
+ bl_undo = False
+
+ def execute(self, context):
+ sce = context.scene
+ rd = sce.render_data
+ prefs = context.user_preferences
+
+ preset = prefs.filepaths.animation_player_preset
+ player_path = prefs.filepaths.animation_player
+
+ # try and guess a command line if it doesn't exist
+ if player_path == '':
+ if preset == 'BLENDER24':
+ player_path = 'blender'
+ elif preset == 'DJV':
+ player_path = 'djv_view'
+
+ # doesn't support ### frame notation yet
+ file = "%s%04d" % (rd.output_path, sce.start_frame)
+ if rd.file_extensions:
+ file += '.' + img_format_exts[rd.file_format]
+
+ cmd = [player_path]
+ # extra options, fps controls etc.
+ if preset == 'BLENDER24':
+ opts = ["-a", "-f", str(rd.fps), str(rd.fps_base), file]
+ cmd.extend(opts)
+ elif preset == 'DJV':
+ opts = [file, "-playback_speed", str(rd.fps)]
+ cmd.extend(opts)
+ else: # 'CUSTOM'
+ cmd.extend(file)
+
+ # launch it
+ try:
+ process = subprocess.Popen(cmd)
+ except:
+ pass
+
+ return('FINISHED',)
+
+bpy.ops.add(PlayRenderedAnim) \ No newline at end of file
diff --git a/release/scripts/op/wm.py b/release/scripts/op/wm.py
index 7000eaffebf..a61c6d2f301 100644
--- a/release/scripts/op/wm.py
+++ b/release/scripts/op/wm.py
@@ -30,7 +30,7 @@ class MESH_OT_delete_edgeloop(bpy.types.Operator):
bl_label = "Delete Edge Loop"
def execute(self, context):
- bpy.ops.tfm.edge_slide(value=1.0)
+ bpy.ops.transform.edge_slide(value=1.0)
bpy.ops.mesh.select_more()
bpy.ops.mesh.remove_doubles()
diff --git a/release/scripts/ui/properties_data_armature.py b/release/scripts/ui/properties_data_armature.py
index 1024ddc7836..1145202332e 100644
--- a/release/scripts/ui/properties_data_armature.py
+++ b/release/scripts/ui/properties_data_armature.py
@@ -128,8 +128,8 @@ class DATA_PT_bone_groups(DataButtonsPanel):
col = row.column(align=True)
col.active = (ob.proxy is None)
- col.operator("pose.group_add", icon='ICON_ZOOMIN', text="")
- col.operator("pose.group_remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("pose.group_add", icon='ZOOMIN', text="")
+ col.operator("pose.group_remove", icon='ZOOMOUT', text="")
group = pose.active_bone_group
if group:
diff --git a/release/scripts/ui/properties_data_bone.py b/release/scripts/ui/properties_data_bone.py
index 4a10ff80a32..982a4911694 100644
--- a/release/scripts/ui/properties_data_bone.py
+++ b/release/scripts/ui/properties_data_bone.py
@@ -43,7 +43,7 @@ class BONE_PT_context_bone(BoneButtonsPanel):
bone = context.edit_bone
row = layout.row()
- row.label(text="", icon='ICON_BONE_DATA')
+ row.label(text="", icon='BONE_DATA')
row.prop(bone, "name", text="")
diff --git a/release/scripts/ui/properties_data_mesh.py b/release/scripts/ui/properties_data_mesh.py
index 46866a89671..d6cdcfc2de9 100644
--- a/release/scripts/ui/properties_data_mesh.py
+++ b/release/scripts/ui/properties_data_mesh.py
@@ -114,12 +114,12 @@ class DATA_PT_vertex_groups(DataButtonsPanel):
row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=rows)
col = row.column(align=True)
- col.operator("object.vertex_group_add", icon='ICON_ZOOMIN', text="")
- col.operator("object.vertex_group_remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
+ col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="")
- col.operator("object.vertex_group_copy", icon='ICON_COPY_ID', text="")
+ col.operator("object.vertex_group_copy", icon='COPY_ID', text="")
if ob.data.users > 1:
- col.operator("object.vertex_group_copy_to_linked", icon='ICON_LINK_AREA', text="")
+ col.operator("object.vertex_group_copy_to_linked", icon='LINK_AREA', text="")
if group:
row = layout.row()
@@ -170,15 +170,15 @@ class DATA_PT_shape_keys(DataButtonsPanel):
col = row.column()
sub = col.column(align=True)
- sub.operator("object.shape_key_add", icon='ICON_ZOOMIN', text="")
- sub.operator("object.shape_key_remove", icon='ICON_ZOOMOUT', text="")
+ sub.operator("object.shape_key_add", icon='ZOOMIN', text="")
+ sub.operator("object.shape_key_remove", icon='ZOOMOUT', text="")
if kb:
col.separator()
sub = col.column(align=True)
- sub.operator("object.shape_key_move", icon='ICON_TRIA_UP', text="").type = 'UP'
- sub.operator("object.shape_key_move", icon='ICON_TRIA_DOWN', text="").type = 'DOWN'
+ sub.operator("object.shape_key_move", icon='TRIA_UP', text="").type = 'UP'
+ sub.operator("object.shape_key_move", icon='TRIA_DOWN', text="").type = 'DOWN'
split = layout.split(percentage=0.4)
row = split.row()
@@ -198,18 +198,18 @@ class DATA_PT_shape_keys(DataButtonsPanel):
subsub = sub.row(align=True)
subsub.active = enable_edit_value
if ob.shape_key_lock:
- subsub.prop(ob, "shape_key_lock", icon='ICON_PINNED', text="")
+ subsub.prop(ob, "shape_key_lock", icon='PINNED', text="")
else:
- subsub.prop(ob, "shape_key_lock", icon='ICON_UNPINNED', text="")
+ subsub.prop(ob, "shape_key_lock", icon='UNPINNED', text="")
if kb.mute:
- subsub.prop(kb, "mute", icon='ICON_MUTE_IPO_ON', text="")
+ subsub.prop(kb, "mute", icon='MUTE_IPO_ON', text="")
else:
- subsub.prop(kb, "mute", icon='ICON_MUTE_IPO_OFF', text="")
+ subsub.prop(kb, "mute", icon='MUTE_IPO_OFF', text="")
sub.prop(ob, "shape_key_edit_mode", text="")
sub = row.row(align=True)
- sub.operator("object.shape_key_mirror", icon='ICON_ARROW_LEFTRIGHT', text="")
- sub.operator("object.shape_key_clear", icon='ICON_X', text="")
+ sub.operator("object.shape_key_mirror", icon='ARROW_LEFTRIGHT', text="")
+ sub.operator("object.shape_key_clear", icon='X', text="")
row = layout.row()
@@ -256,8 +256,8 @@ class DATA_PT_uv_texture(DataButtonsPanel):
col.template_list(me, "uv_textures", me, "active_uv_texture_index", rows=2)
col = row.column(align=True)
- col.operator("mesh.uv_texture_add", icon='ICON_ZOOMIN', text="")
- col.operator("mesh.uv_texture_remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
+ col.operator("mesh.uv_texture_remove", icon='ZOOMOUT', text="")
lay = me.active_uv_texture
if lay:
@@ -278,8 +278,8 @@ class DATA_PT_vertex_colors(DataButtonsPanel):
col.template_list(me, "vertex_colors", me, "active_vertex_color_index", rows=2)
col = row.column(align=True)
- col.operator("mesh.vertex_color_add", icon='ICON_ZOOMIN', text="")
- col.operator("mesh.vertex_color_remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="")
+ col.operator("mesh.vertex_color_remove", icon='ZOOMOUT', text="")
lay = me.active_vertex_color
if lay:
diff --git a/release/scripts/ui/properties_material.py b/release/scripts/ui/properties_material.py
index 50fc0a7ded9..64e36a26961 100644
--- a/release/scripts/ui/properties_material.py
+++ b/release/scripts/ui/properties_material.py
@@ -89,9 +89,9 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel):
row.template_list(ob, "materials", ob, "active_material_index", rows=2)
col = row.column(align=True)
- col.operator("object.material_slot_add", icon='ICON_ZOOMIN', text="")
- col.operator("object.material_slot_remove", icon='ICON_ZOOMOUT', text="")
- col.operator("object.material_slot_copy", icon='ICON_COPY_ID', text="")
+ col.operator("object.material_slot_add", icon='ZOOMIN', text="")
+ col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
+ col.operator("object.material_slot_copy", icon='COPY_ID', text="")
if ob.mode == 'EDIT':
row = layout.row(align=True)
diff --git a/release/scripts/ui/properties_object.py b/release/scripts/ui/properties_object.py
index c7c1ce24d59..ff7e15cde58 100644
--- a/release/scripts/ui/properties_object.py
+++ b/release/scripts/ui/properties_object.py
@@ -38,7 +38,7 @@ class OBJECT_PT_context_object(ObjectButtonsPanel):
ob = context.object
row = layout.row()
- row.label(text="", icon='ICON_OBJECT_DATA')
+ row.label(text="", icon='OBJECT_DATA')
row.prop(ob, "name", text="")
@@ -162,7 +162,7 @@ class OBJECT_PT_groups(ObjectButtonsPanel):
row = col.box().row()
row.prop(group, "name", text="")
- row.operator("object.group_remove", text="", icon='ICON_X')
+ row.operator("object.group_remove", text="", icon='X')
split = col.box().split()
diff --git a/release/scripts/ui/properties_object_constraint.py b/release/scripts/ui/properties_object_constraint.py
index d6552585191..0436da546bc 100644
--- a/release/scripts/ui/properties_object_constraint.py
+++ b/release/scripts/ui/properties_object_constraint.py
@@ -59,7 +59,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
if wide_ui:
if target and owner:
- row.label(icon='ICON_ARROW_LEFTRIGHT')
+ row.label(icon='ARROW_LEFTRIGHT')
else:
row = layout.row()
if owner:
diff --git a/release/scripts/ui/properties_particle.py b/release/scripts/ui/properties_particle.py
index 3577ba961b3..a33a1a12f1b 100644
--- a/release/scripts/ui/properties_particle.py
+++ b/release/scripts/ui/properties_particle.py
@@ -66,8 +66,8 @@ class PARTICLE_PT_particles(ParticleButtonsPanel):
row.template_list(ob, "particle_systems", ob, "active_particle_system_index", rows=2)
col = row.column(align=True)
- col.operator("object.particle_system_add", icon='ICON_ZOOMIN', text="")
- col.operator("object.particle_system_remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("object.particle_system_add", icon='ZOOMIN', text="")
+ col.operator("object.particle_system_remove", icon='ZOOMOUT', text="")
if psys and not psys.settings:
split = layout.split(percentage=0.32)
@@ -457,12 +457,12 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
col = row.column()
sub = col.row()
subsub = sub.column(align=True)
- subsub.operator("particle.new_target", icon='ICON_ZOOMIN', text="")
- subsub.operator("particle.target_remove", icon='ICON_ZOOMOUT', text="")
+ subsub.operator("particle.new_target", icon='ZOOMIN', text="")
+ subsub.operator("particle.target_remove", icon='ZOOMOUT', text="")
sub = col.row()
subsub = sub.column(align=True)
- subsub.operator("particle.target_move_up", icon='VICON_MOVE_UP', text="")
- subsub.operator("particle.target_move_down", icon='VICON_MOVE_DOWN', text="")
+ subsub.operator("particle.target_move_up", icon='MOVE_UP_VEC', text="")
+ subsub.operator("particle.target_move_down", icon='MOVE_DOWN_VEC', text="")
key = psys.active_particle_target
if key:
@@ -512,11 +512,11 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
#row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
#col = row.row()
#sub = col.row(align=True)
- #sub.operator("boid.state_add", icon='ICON_ZOOMIN', text="")
- #sub.operator("boid.state_del", icon='ICON_ZOOMOUT', text="")
+ #sub.operator("boid.state_add", icon='ZOOMIN', text="")
+ #sub.operator("boid.state_del", icon='ZOOMOUT', text="")
#sub = row.row(align=True)
- #sub.operator("boid.state_move_up", icon='VICON_MOVE_UP', text="")
- #sub.operator("boid.state_move_down", icon='VICON_MOVE_DOWN', text="")
+ #sub.operator("boid.state_move_up", icon='MOVE_UP_VEC', text="")
+ #sub.operator("boid.state_move_down", icon='MOVE_DOWN_VEC', text="")
state = boids.active_boid_state
@@ -535,12 +535,12 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
col = row.column()
sub = col.row()
subsub = sub.column(align=True)
- subsub.operator_menu_enum("boid.rule_add", "type", icon='ICON_ZOOMIN', text="")
- subsub.operator("boid.rule_del", icon='ICON_ZOOMOUT', text="")
+ subsub.operator_menu_enum("boid.rule_add", "type", icon='ZOOMIN', text="")
+ subsub.operator("boid.rule_del", icon='ZOOMOUT', text="")
sub = col.row()
subsub = sub.column(align=True)
- subsub.operator("boid.rule_move_up", icon='VICON_MOVE_UP', text="")
- subsub.operator("boid.rule_move_down", icon='VICON_MOVE_DOWN', text="")
+ subsub.operator("boid.rule_move_up", icon='MOVE_UP_VEC', text="")
+ subsub.operator("boid.rule_move_down", icon='MOVE_DOWN_VEC', text="")
rule = state.active_boid_rule
@@ -548,8 +548,8 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
row = layout.row()
row.prop(rule, "name", text="")
#somebody make nice icons for boids here please! -jahka
- row.prop(rule, "in_air", icon='VICON_MOVE_UP', text="")
- row.prop(rule, "on_land", icon='VICON_MOVE_DOWN', text="")
+ row.prop(rule, "in_air", icon='MOVE_UP_VEC', text="")
+ row.prop(rule, "on_land", icon='MOVE_DOWN_VEC', text="")
row = layout.row()
@@ -695,10 +695,10 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
col = row.column()
sub = col.row()
subsub = sub.column(align=True)
- subsub.operator("particle.dupliob_copy", icon='ICON_ZOOMIN', text="")
- subsub.operator("particle.dupliob_remove", icon='ICON_ZOOMOUT', text="")
- subsub.operator("particle.dupliob_move_up", icon='VICON_MOVE_UP', text="")
- subsub.operator("particle.dupliob_move_down", icon='VICON_MOVE_DOWN', text="")
+ subsub.operator("particle.dupliob_copy", icon='ZOOMIN', text="")
+ subsub.operator("particle.dupliob_remove", icon='ZOOMOUT', text="")
+ subsub.operator("particle.dupliob_move_up", icon='MOVE_UP_VEC', text="")
+ subsub.operator("particle.dupliob_move_down", icon='MOVE_DOWN_VEC', text="")
weight = part.active_dupliweight
if weight:
diff --git a/release/scripts/ui/properties_physics_common.py b/release/scripts/ui/properties_physics_common.py
index 7c1d71302ec..26411b227a8 100644
--- a/release/scripts/ui/properties_physics_common.py
+++ b/release/scripts/ui/properties_physics_common.py
@@ -30,8 +30,8 @@ def point_cache_ui(self, context, cache, enabled, particles, smoke):
row = layout.row()
row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2)
col = row.column(align=True)
- col.operator("ptcache.add", icon='ICON_ZOOMIN', text="")
- col.operator("ptcache.remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("ptcache.add", icon='ZOOMIN', text="")
+ col.operator("ptcache.remove", icon='ZOOMOUT', text="")
row = layout.row()
row.label(text="File Name:")
diff --git a/release/scripts/ui/properties_physics_fluid.py b/release/scripts/ui/properties_physics_fluid.py
index a126002c211..66a2d454ca1 100644
--- a/release/scripts/ui/properties_physics_fluid.py
+++ b/release/scripts/ui/properties_physics_fluid.py
@@ -72,7 +72,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel):
layout.prop(fluid, "type", text="")
if fluid.type == 'DOMAIN':
- layout.operator("fluid.bake", text="Bake Fluid Simulation", icon='ICON_MOD_FLUIDSIM')
+ layout.operator("fluid.bake", text="Bake Fluid Simulation", icon='MOD_FLUIDSIM')
split = layout.split()
col = split.column()
diff --git a/release/scripts/ui/properties_render.py b/release/scripts/ui/properties_render.py
index aa04e277f69..7f5ce213aed 100644
--- a/release/scripts/ui/properties_render.py
+++ b/release/scripts/ui/properties_render.py
@@ -53,11 +53,11 @@ class RENDER_PT_render(RenderButtonsPanel):
split = layout.split()
col = split.column()
- col.operator("screen.render", text="Image", icon='ICON_RENDER_STILL')
+ col.operator("screen.render", text="Image", icon='RENDER_STILL')
if wide_ui:
col = split.column()
- col.operator("screen.render", text="Animation", icon='ICON_RENDER_ANIMATION').animation = True
+ col.operator("screen.render", text="Animation", icon='RENDER_ANIMATION').animation = True
layout.prop(rd, "display_mode", text="Display")
@@ -78,8 +78,8 @@ class RENDER_PT_layers(RenderButtonsPanel):
row.template_list(rd, "layers", rd, "active_layer_index", rows=2)
col = row.column(align=True)
- col.operator("scene.render_layer_add", icon='ICON_ZOOMIN', text="")
- col.operator("scene.render_layer_remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
+ col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="")
rl = rd.layers[rd.active_layer_index]
@@ -145,19 +145,19 @@ class RENDER_PT_layers(RenderButtonsPanel):
col.prop(rl, "pass_diffuse")
row = col.row()
row.prop(rl, "pass_specular")
- row.prop(rl, "pass_specular_exclude", text="", icon='ICON_X')
+ row.prop(rl, "pass_specular_exclude", text="", icon='X')
row = col.row()
row.prop(rl, "pass_shadow")
- row.prop(rl, "pass_shadow_exclude", text="", icon='ICON_X')
+ row.prop(rl, "pass_shadow_exclude", text="", icon='X')
row = col.row()
row.prop(rl, "pass_ao")
- row.prop(rl, "pass_ao_exclude", text="", icon='ICON_X')
+ row.prop(rl, "pass_ao_exclude", text="", icon='X')
row = col.row()
row.prop(rl, "pass_reflection")
- row.prop(rl, "pass_reflection_exclude", text="", icon='ICON_X')
+ row.prop(rl, "pass_reflection_exclude", text="", icon='X')
row = col.row()
row.prop(rl, "pass_refraction")
- row.prop(rl, "pass_refraction_exclude", text="", icon='ICON_X')
+ row.prop(rl, "pass_refraction_exclude", text="", icon='X')
class RENDER_PT_shading(RenderButtonsPanel):
diff --git a/release/scripts/ui/properties_scene.py b/release/scripts/ui/properties_scene.py
index 8325889e644..622ce06c567 100644
--- a/release/scripts/ui/properties_scene.py
+++ b/release/scripts/ui/properties_scene.py
@@ -85,8 +85,8 @@ class SCENE_PT_keying_sets(SceneButtonsPanel):
col.template_list(scene, "keying_sets", scene, "active_keying_set_index", rows=2)
col = row.column(align=True)
- col.operator("anim.keying_set_add", icon='ICON_ZOOMIN', text="")
- col.operator("anim.keying_set_remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("anim.keying_set_add", icon='ZOOMIN', text="")
+ col.operator("anim.keying_set_remove", icon='ZOOMOUT', text="")
ks = scene.active_keying_set
if ks:
@@ -100,7 +100,8 @@ class SCENE_PT_keying_sets(SceneButtonsPanel):
col = row.column()
col.label(text="Keyframing Settings:")
col.prop(ks, "insertkey_needed", text="Needed")
- col.prop(ks, "insertkey_visual", text="Visual")
+ col.prop(ks, "insertkey_visual", text="Visual")
+ col.prop(ks, "insertkey_xyz_to_rgb", text="XYZ to RGB")
class SCENE_PT_keying_set_paths(SceneButtonsPanel):
@@ -125,15 +126,15 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel):
col.template_list(ks, "paths", ks, "active_path_index", rows=2)
col = row.column(align=True)
- col.operator("anim.keying_set_path_add", icon='ICON_ZOOMIN', text="")
- col.operator("anim.keying_set_path_remove", icon='ICON_ZOOMOUT', text="")
+ col.operator("anim.keying_set_path_add", icon='ZOOMIN', text="")
+ col.operator("anim.keying_set_path_remove", icon='ZOOMOUT', text="")
ksp = ks.active_path
if ksp:
col = layout.column()
col.label(text="Target:")
col.template_any_ID(ksp, "id", "id_type")
- col.template_path_builder(ksp, "rna_path", ksp.id)
+ col.template_path_builder(ksp, "data_path", ksp.id)
row = layout.row()
diff --git a/release/scripts/ui/properties_texture.py b/release/scripts/ui/properties_texture.py
index 1844599e957..4471f6f9644 100644
--- a/release/scripts/ui/properties_texture.py
+++ b/release/scripts/ui/properties_texture.py
@@ -99,8 +99,8 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel):
row.template_list(idblock, "textures", idblock, "active_texture_index", rows=2)
col = row.column(align=True)
- col.operator("texture.slot_move", text="", icon='ICON_TRIA_UP').type = 'UP'
- col.operator("texture.slot_move", text="", icon='ICON_TRIA_DOWN').type = 'DOWN'
+ col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
+ col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
if wide_ui:
diff --git a/release/scripts/ui/space_dopesheet.py b/release/scripts/ui/space_dopesheet.py
index a669140d38e..f9381432e27 100644
--- a/release/scripts/ui/space_dopesheet.py
+++ b/release/scripts/ui/space_dopesheet.py
@@ -57,8 +57,8 @@ class DOPESHEET_HT_header(bpy.types.Header):
layout.prop(st, "autosnap", text="")
row = layout.row(align=True)
- row.operator("action.copy", text="", icon='ICON_COPYDOWN')
- row.operator("action.paste", text="", icon='ICON_PASTEDOWN')
+ row.operator("action.copy", text="", icon='COPYDOWN')
+ row.operator("action.paste", text="", icon='PASTEDOWN')
class DOPESHEET_MT_view(bpy.types.Menu):
@@ -178,9 +178,9 @@ class DOPESHEET_MT_key_transform(bpy.types.Menu):
layout = self.layout
layout.column()
- layout.operator("tfm.translate", text="Grab/Move")
- layout.operator("tfm.transform", text="Extend").mode = 'TIME_EXTEND'
- layout.operator("tfm.resize", text="Scale")
+ layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.transform", text="Extend").mode = 'TIME_EXTEND'
+ layout.operator("transform.resize", text="Scale")
bpy.types.register(DOPESHEET_HT_header) # header/menu classes
diff --git a/release/scripts/ui/space_filebrowser.py b/release/scripts/ui/space_filebrowser.py
index 3b8734bdb21..47272b9aa32 100644
--- a/release/scripts/ui/space_filebrowser.py
+++ b/release/scripts/ui/space_filebrowser.py
@@ -35,22 +35,22 @@ class FILEBROWSER_HT_header(bpy.types.Header):
row.separator()
row = layout.row(align=True)
- row.operator("file.previous", text="", icon='ICON_BACK')
- row.operator("file.next", text="", icon='ICON_FORWARD')
- row.operator("file.parent", text="", icon='ICON_FILE_PARENT')
- row.operator("file.refresh", text="", icon='ICON_FILE_REFRESH')
+ row.operator("file.previous", text="", icon='BACK')
+ row.operator("file.next", text="", icon='FORWARD')
+ row.operator("file.parent", text="", icon='FILE_PARENT')
+ row.operator("file.refresh", text="", icon='FILE_REFRESH')
row = layout.row()
row.separator()
row = layout.row(align=True)
- row.operator("file.directory_new", text="", icon='ICON_NEWFOLDER')
+ row.operator("file.directory_new", text="", icon='NEWFOLDER')
layout.prop(params, "display", expand=True, text="")
layout.prop(params, "sort", expand=True, text="")
layout.prop(params, "hide_dot", text="Hide Invisible")
- layout.prop(params, "do_filter", text="", icon='ICON_FILTER')
+ layout.prop(params, "do_filter", text="", icon='FILTER')
row = layout.row(align=True)
row.active = params.do_filter
diff --git a/release/scripts/ui/space_graph.py b/release/scripts/ui/space_graph.py
index c24bf460147..57e42f9d48c 100644
--- a/release/scripts/ui/space_graph.py
+++ b/release/scripts/ui/space_graph.py
@@ -46,14 +46,14 @@ class GRAPH_HT_header(bpy.types.Header):
layout.prop(st, "pivot_point", text="", icon_only=True)
row = layout.row(align=True)
- row.operator("graph.copy", text="", icon='ICON_COPYDOWN')
- row.operator("graph.paste", text="", icon='ICON_PASTEDOWN')
+ row.operator("graph.copy", text="", icon='COPYDOWN')
+ row.operator("graph.paste", text="", icon='PASTEDOWN')
row = layout.row(align=True)
if st.has_ghost_curves:
- row.operator("graph.ghost_curves_clear", text="", icon='ICON_GHOST_DISABLED')
+ row.operator("graph.ghost_curves_clear", text="", icon='GHOST_DISABLED')
else:
- row.operator("graph.ghost_curves_create", text="", icon='ICON_GHOST_ENABLED')
+ row.operator("graph.ghost_curves_create", text="", icon='GHOST_ENABLED')
class GRAPH_MT_view(bpy.types.Menu):
@@ -67,7 +67,7 @@ class GRAPH_MT_view(bpy.types.Menu):
layout.column()
layout.separator()
- layout.operator("graph.properties", icon="ICON_MENU_PANEL")
+ layout.operator("graph.properties", icon='MENU_PANEL')
layout.prop(st, "show_cframe_indicator")
layout.prop(st, "show_cursor")
@@ -76,9 +76,9 @@ class GRAPH_MT_view(bpy.types.Menu):
layout.separator()
if st.show_handles:
- layout.operator("graph.handles_view_toggle", icon="ICON_CHECKBOX_HLT", text="Show All Handles")
+ layout.operator("graph.handles_view_toggle", icon='CHECKBOX_HLT', text="Show All Handles")
else:
- layout.operator("graph.handles_view_toggle", icon="ICON_CHECKBOX_DEHLT", text="Show All Handles")
+ layout.operator("graph.handles_view_toggle", icon='CHECKBOX_DEHLT', text="Show All Handles")
layout.prop(st, "only_selected_curves_handles")
layout.prop(st, "only_selected_keyframe_handles")
layout.operator("anim.time_toggle")
@@ -181,10 +181,10 @@ class GRAPH_MT_key_transform(bpy.types.Menu):
layout = self.layout
layout.column()
- layout.operator("tfm.translate", text="Grab/Move")
- layout.operator("tfm.transform", text="Extend").mode = 'TIME_EXTEND'
- layout.operator("tfm.rotate", text="Rotate")
- layout.operator("tfm.resize", text="Scale")
+ layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.transform", text="Extend").mode = 'TIME_EXTEND'
+ layout.operator("transform.rotate", text="Rotate")
+ layout.operator("transform.resize", text="Scale")
bpy.types.register(GRAPH_HT_header) # header/menu classes
diff --git a/release/scripts/ui/space_image.py b/release/scripts/ui/space_image.py
index 5714a3d2548..27d0aa91349 100644
--- a/release/scripts/ui/space_image.py
+++ b/release/scripts/ui/space_image.py
@@ -34,7 +34,7 @@ class IMAGE_MT_view(bpy.types.Menu):
show_uvedit = sima.show_uvedit
- layout.operator("image.properties", icon='ICON_MENU_PANEL')
+ layout.operator("image.properties", icon='MENU_PANEL')
layout.separator()
@@ -150,9 +150,9 @@ class IMAGE_MT_uvs_transform(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.operator("tfm.translate")
- layout.operator("tfm.rotate")
- layout.operator("tfm.resize")
+ layout.operator("transform.translate")
+ layout.operator("transform.rotate")
+ layout.operator("transform.resize")
class IMAGE_MT_uvs_snap(bpy.types.Menu):
@@ -179,8 +179,8 @@ class IMAGE_MT_uvs_mirror(bpy.types.Menu):
layout = self.layout
layout.operator_context = 'EXEC_REGION_WIN'
- layout.operator("tfm.mirror", text="X Axis").constraint_axis[0] = True
- layout.operator("tfm.mirror", text="Y Axis").constraint_axis[1] = True
+ layout.operator("transform.mirror", text="X Axis").constraint_axis[0] = True
+ layout.operator("transform.mirror", text="Y Axis").constraint_axis[1] = True
class IMAGE_MT_uvs_weldalign(bpy.types.Menu):
@@ -287,9 +287,13 @@ class IMAGE_HT_header(bpy.types.Header):
layout.prop(uvedit, "sticky_selection_mode", text="", icon_only=True)
row = layout.row(align=True)
+ row.prop(settings, "proportional_editing", text="", icon_only=True)
+ if settings.proportional_editing != 'DISABLED':
+ row.prop(settings, "proportional_editing_falloff", text="", icon_only=True)
+
+ row = layout.row(align=True)
row.prop(settings, "snap", text="")
- if settings.snap:
- row.prop(settings, "snap_mode", text="")
+ row.prop(settings, "snap_element", text="", icon_only=True)
# mesh = context.edit_object.data
# row.prop_object(mesh, "active_uv_layer", mesh, "uv_textures")
@@ -307,12 +311,12 @@ class IMAGE_HT_header(bpy.types.Header):
row = layout.row(align=True)
if ima.type == 'COMPOSITE':
- row.operator("image.record_composite", icon='ICON_REC')
+ row.operator("image.record_composite", icon='REC')
if ima.type == 'COMPOSITE' and ima.source in ('MOVIE', 'SEQUENCE'):
- row.operator("image.play_composite", icon='ICON_PLAY')
+ row.operator("image.play_composite", icon='PLAY')
if show_uvedit or sima.image_painting:
- layout.prop(sima, "update_automatically", text="")
+ layout.prop(sima, "update_automatically", text="", icon_only=True, icon='LOCKED')
class IMAGE_PT_image_properties(bpy.types.Panel):
diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py
index ece06e1751a..57410daf2b5 100644
--- a/release/scripts/ui/space_info.py
+++ b/release/scripts/ui/space_info.py
@@ -47,7 +47,7 @@ class INFO_HT_header(bpy.types.Header):
sub.menu("INFO_MT_help")
if window.screen.fullscreen:
- layout.operator("screen.back_to_previous", icon="ICON_SCREEN_BACK", text="Back to Previous")
+ layout.operator("screen.back_to_previous", icon='SCREEN_BACK', text="Back to Previous")
layout.separator()
else:
layout.template_ID(context.window, "screen", new="screen.new", unlink="screen.delete")
@@ -66,7 +66,7 @@ class INFO_HT_header(bpy.types.Header):
layout.label(text=scene.statistics())
- layout.operator("wm.window_fullscreen_toggle", icon='ICON_FULLSCREEN_ENTER', text="")
+ layout.operator("wm.window_fullscreen_toggle", icon='FULLSCREEN_ENTER', text="")
class INFO_MT_file(bpy.types.Menu):
@@ -76,9 +76,9 @@ class INFO_MT_file(bpy.types.Menu):
layout = self.layout
layout.operator_context = 'EXEC_AREA'
- layout.operator("wm.read_homefile", text="New", icon='ICON_NEW')
+ layout.operator("wm.read_homefile", text="New", icon='NEW')
layout.operator_context = 'INVOKE_AREA'
- layout.operator("wm.open_mainfile", text="Open...", icon='ICON_FILE_FOLDER')
+ layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
layout.operator_menu_enum("wm.open_recentfile", "file", text="Open Recent")
layout.operator("wm.recover_last_session")
layout.operator("wm.recover_auto_save", text="Recover Auto Save...")
@@ -86,13 +86,13 @@ class INFO_MT_file(bpy.types.Menu):
layout.separator()
layout.operator_context = 'INVOKE_AREA'
- layout.operator("wm.save_mainfile", text="Save", icon='ICON_FILE_TICK')
+ layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK')
layout.operator_context = 'INVOKE_AREA'
layout.operator("wm.save_as_mainfile", text="Save As...")
layout.separator()
- layout.operator("screen.userpref_show", text="User Preferences...", icon='ICON_PREFERENCES')
+ layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES')
layout.operator("wm.read_homefile", text="Load Factory Settings").factory = True
layout.separator()
@@ -113,7 +113,7 @@ class INFO_MT_file(bpy.types.Menu):
layout.separator()
layout.operator_context = 'EXEC_AREA'
- layout.operator("wm.exit_blender", text="Quit", icon='ICON_QUIT')
+ layout.operator("wm.exit_blender", text="Quit", icon='QUIT')
# test for expanding menus
'''
@@ -171,16 +171,25 @@ class INFO_MT_mesh_add(dynamic_menu.DynMenu):
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("mesh.primitive_plane_add", icon='ICON_MESH_PLANE', text="Plane")
- layout.operator("mesh.primitive_cube_add", icon='ICON_MESH_CUBE', text="Cube")
- layout.operator("mesh.primitive_circle_add", icon='ICON_MESH_CIRCLE', text="Circle")
- layout.operator("mesh.primitive_uv_sphere_add", icon='ICON_MESH_UVSPHERE', text="UV Sphere")
- layout.operator("mesh.primitive_ico_sphere_add", icon='ICON_MESH_ICOSPHERE', text="Icosphere")
- layout.operator("mesh.primitive_tube_add", icon='ICON_MESH_TUBE', text="Tube")
- layout.operator("mesh.primitive_cone_add", icon='ICON_MESH_CONE', text="Cone")
+ layout.operator("mesh.primitive_plane_add", icon='MESH_PLANE', text="Plane")
+ layout.operator("mesh.primitive_cube_add", icon='MESH_CUBE', text="Cube")
+ layout.operator("mesh.primitive_circle_add", icon='MESH_CIRCLE', text="Circle")
+ layout.operator("mesh.primitive_uv_sphere_add", icon='MESH_UVSPHERE', text="UV Sphere")
+ layout.operator("mesh.primitive_ico_sphere_add", icon='MESH_ICOSPHERE', text="Icosphere")
+ layout.operator("mesh.primitive_tube_add", icon='MESH_TUBE', text="Tube")
+ layout.operator("mesh.primitive_cone_add", icon='MESH_CONE', text="Cone")
layout.separator()
- layout.operator("mesh.primitive_grid_add", icon='ICON_MESH_GRID', text="Grid")
- layout.operator("mesh.primitive_monkey_add", icon='ICON_MESH_MONKEY', text="Monkey")
+ 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_armature_add(dynamic_menu.DynMenu):
+ bl_idname = "INFO_MT_armature_add"
+ bl_label = "Armature"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA')
class INFO_MT_add(bpy.types.Menu):
@@ -191,37 +200,30 @@ class INFO_MT_add(bpy.types.Menu):
layout.operator_context = 'EXEC_SCREEN'
- #layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH')
- layout.menu("INFO_MT_mesh_add", icon='ICON_OUTLINER_OB_MESH')
-
- layout.operator_menu_enum("object.curve_add", "type", text="Curve", icon='ICON_OUTLINER_OB_CURVE')
- layout.operator_menu_enum("object.surface_add", "type", text="Surface", icon='ICON_OUTLINER_OB_SURFACE')
- layout.operator_menu_enum("object.metaball_add", "type", 'META', text="Metaball", icon='ICON_OUTLINER_OB_META')
- layout.operator("object.text_add", text="Text", icon='ICON_OUTLINER_OB_FONT')
+ #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.surface_add", "type", text="Surface", icon='OUTLINER_OB_SURFACE')
+ layout.operator_menu_enum("object.metaball_add", "type", 'META', text="Metaball", icon='OUTLINER_OB_META')
+ layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
layout.separator()
layout.operator_context = 'INVOKE_REGION_WIN'
-
- layout.operator("object.armature_add", text="Armature", icon='ICON_OUTLINER_OB_ARMATURE')
- layout.operator("object.add", text="Lattice", icon='ICON_OUTLINER_OB_LATTICE').type = 'LATTICE'
- layout.operator("object.add", text="Empty", icon='ICON_OUTLINER_OB_EMPTY').type = 'EMPTY'
-
+ layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
+ layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
+ layout.operator("object.add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'EMPTY'
layout.separator()
- layout.operator("object.add", text="Camera", icon='ICON_OUTLINER_OB_CAMERA').type = 'CAMERA'
-
+ layout.operator("object.add", text="Camera", icon='OUTLINER_OB_CAMERA').type = 'CAMERA'
layout.operator_context = 'EXEC_SCREEN'
-
- layout.operator_menu_enum("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP')
-
+ layout.operator_menu_enum("object.lamp_add", "type", 'LAMP', text="Lamp", icon='OUTLINER_OB_LAMP')
layout.separator()
- layout.operator_menu_enum("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY')
-
+ layout.operator_menu_enum("object.effector_add", "type", 'EMPTY', text="Force Field", icon='OUTLINER_OB_EMPTY')
layout.separator()
- layout.operator_menu_enum("object.group_instance_add", "type", text="Group Instance", icon='ICON_OUTLINER_OB_EMPTY')
+ layout.operator_menu_enum("object.group_instance_add", "type", text="Group Instance", icon='OUTLINER_OB_EMPTY')
class INFO_MT_game(bpy.types.Menu):
@@ -250,8 +252,8 @@ class INFO_MT_render(bpy.types.Menu):
# rd = context.scene.render_data
- layout.operator("screen.render", text="Render Image", icon='ICON_RENDER_STILL')
- layout.operator("screen.render", text="Render Animation", icon='ICON_RENDER_ANIMATION').animation = True
+ layout.operator("screen.render", text="Render Image", icon='RENDER_STILL')
+ layout.operator("screen.render", text="Render Animation", icon='RENDER_ANIMATION').animation = True
layout.separator()
@@ -261,6 +263,7 @@ class INFO_MT_render(bpy.types.Menu):
layout.separator()
layout.operator("screen.render_view_show")
+ layout.operator("screen.play_rendered_anim")
class INFO_MT_help(bpy.types.Menu):
@@ -269,19 +272,19 @@ class INFO_MT_help(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.operator("help.manual", icon='ICON_HELP')
- layout.operator("help.release_logs", icon='ICON_URL')
+ layout.operator("help.manual", icon='HELP')
+ layout.operator("help.release_logs", icon='URL')
layout.separator()
- layout.operator("help.blender_website", icon='ICON_URL')
- layout.operator("help.blender_eshop", icon='ICON_URL')
- layout.operator("help.developer_community", icon='ICON_URL')
- layout.operator("help.user_community", icon='ICON_URL')
+ 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.separator()
- layout.operator("help.report_bug", icon='ICON_URL')
+ layout.operator("help.report_bug", icon='URL')
layout.separator()
- layout.operator("help.python_api", icon='ICON_URL')
+ layout.operator("help.python_api", icon='URL')
layout.operator("help.operator_cheat_sheet")
bpy.types.register(INFO_HT_header)
@@ -291,6 +294,7 @@ bpy.types.register(INFO_MT_file_export)
bpy.types.register(INFO_MT_file_external_data)
bpy.types.register(INFO_MT_add)
bpy.types.register(INFO_MT_mesh_add)
+bpy.types.register(INFO_MT_armature_add)
bpy.types.register(INFO_MT_game)
bpy.types.register(INFO_MT_render)
bpy.types.register(INFO_MT_help)
diff --git a/release/scripts/ui/space_logic.py b/release/scripts/ui/space_logic.py
index e547da6bb8f..f2fdbd3a15a 100644
--- a/release/scripts/ui/space_logic.py
+++ b/release/scripts/ui/space_logic.py
@@ -43,7 +43,7 @@ class LOGIC_PT_properties(bpy.types.Panel):
row.prop(prop, "name", text="")
row.prop(prop, "type", text="")
row.prop(prop, "value", text="", toggle=True) # we dont care about the type. rna will display correctly
- row.prop(prop, "debug", text="", toggle=True, icon='ICON_INFO')
- row.operator("object.game_property_remove", text="", icon='ICON_X').index = i
+ row.prop(prop, "debug", text="", toggle=True, icon='INFO')
+ row.operator("object.game_property_remove", text="", icon='X').index = i
bpy.types.register(LOGIC_PT_properties)
diff --git a/release/scripts/ui/space_nla.py b/release/scripts/ui/space_nla.py
index d17e5e0b8cb..622ebb42ab7 100644
--- a/release/scripts/ui/space_nla.py
+++ b/release/scripts/ui/space_nla.py
@@ -53,7 +53,7 @@ class NLA_MT_view(bpy.types.Menu):
layout.column()
- layout.operator("nla.properties", icon="ICON_MENU_PANEL")
+ layout.operator("nla.properties", icon='MENU_PANEL')
layout.separator()
layout.prop(st, "show_cframe_indicator")
@@ -153,9 +153,9 @@ class NLA_MT_edit_transform(bpy.types.Menu):
layout = self.layout
layout.column()
- layout.operator("tfm.translate", text="Grab/Move")
- layout.operator("tfm.transform", text="Extend").mode = 'TIME_EXTEND'
- layout.operator("tfm.resize", text="Scale")
+ layout.operator("transform.translate", text="Grab/Move")
+ layout.operator("transform.transform", text="Extend").mode = 'TIME_EXTEND'
+ layout.operator("transform.resize", text="Scale")
bpy.types.register(NLA_HT_header) # header/menu classes
diff --git a/release/scripts/ui/space_node.py b/release/scripts/ui/space_node.py
index c05ab767f85..9cf0a0c5ef3 100644
--- a/release/scripts/ui/space_node.py
+++ b/release/scripts/ui/space_node.py
@@ -73,7 +73,7 @@ class NODE_MT_view(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.operator("node.properties", icon='ICON_MENU_PANEL')
+ layout.operator("node.properties", icon='MENU_PANEL')
layout.separator()
layout.operator("view2d.zoom_in")
@@ -109,9 +109,9 @@ class NODE_MT_node(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.operator("tfm.translate")
- layout.operator("tfm.rotate")
- layout.operator("tfm.resize")
+ layout.operator("transform.translate")
+ layout.operator("transform.rotate")
+ layout.operator("transform.resize")
layout.separator()
diff --git a/release/scripts/ui/space_outliner.py b/release/scripts/ui/space_outliner.py
index cc2c6a633ae..f60cb3299b4 100644
--- a/release/scripts/ui/space_outliner.py
+++ b/release/scripts/ui/space_outliner.py
@@ -45,16 +45,16 @@ class OUTLINER_HT_header(bpy.types.Header):
if space.display_mode == 'DATABLOCKS':
row = layout.row(align=True)
- row.operator("outliner.keyingset_add_selected", icon='ICON_ZOOMIN', text="")
- row.operator("outliner.keyingset_remove_selected", icon='ICON_ZOOMOUT', text="")
+ row.operator("outliner.keyingset_add_selected", icon='ZOOMIN', text="")
+ row.operator("outliner.keyingset_remove_selected", icon='ZOOMOUT', text="")
if ks:
row = layout.row(align=False)
row.prop_object(scene, "active_keying_set", scene, "keying_sets", text="")
row = layout.row(align=True)
- row.operator("anim.keyframe_insert", text="", icon='ICON_KEY_HLT')
- row.operator("anim.keyframe_delete", text="", icon='ICON_KEY_DEHLT')
+ row.operator("anim.keyframe_insert", text="", icon='KEY_HLT')
+ row.operator("anim.keyframe_delete", text="", icon='KEY_DEHLT')
else:
row = layout.row(align=False)
row.label(text="No Keying Set active")
diff --git a/release/scripts/ui/space_sequencer.py b/release/scripts/ui/space_sequencer.py
index 026161e23c6..35174033572 100644
--- a/release/scripts/ui/space_sequencer.py
+++ b/release/scripts/ui/space_sequencer.py
@@ -199,8 +199,8 @@ class SEQUENCER_MT_strip(bpy.types.Menu):
layout.operator_context = 'INVOKE_REGION_WIN'
layout.column()
- layout.operator("tfm.transform", text="Grab/Move").mode = 'TRANSLATION'
- layout.operator("tfm.transform", text="Grab/Extend from frame").mode = 'TIME_EXTEND'
+ layout.operator("transform.transform", text="Grab/Move").mode = 'TRANSLATION'
+ layout.operator("transform.transform", text="Grab/Extend from frame").mode = 'TIME_EXTEND'
# uiItemO(layout, NULL, 0, "sequencer.strip_snap"); // TODO - add this operator
layout.separator()
@@ -297,9 +297,9 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel):
row = layout.row()
if strip.mute == True:
- row.prop(strip, "mute", toggle=True, icon='ICON_RESTRICT_VIEW_ON', text="")
+ row.prop(strip, "mute", toggle=True, icon='RESTRICT_VIEW_ON', text="")
elif strip.mute is False:
- row.prop(strip, "mute", toggle=True, icon='ICON_RESTRICT_VIEW_OFF', text="")
+ row.prop(strip, "mute", toggle=True, icon='RESTRICT_VIEW_OFF', text="")
sub = row.row()
sub.active = (not strip.mute)
@@ -401,14 +401,23 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel):
layout.separator()
col = layout.column(align=True)
- col.label(text="Scale X:")
- col.prop(strip, "scale_start_x", text="Start")
- col.prop(strip, "scale_end_x", text="End")
-
- col = layout.column(align=True)
- col.label(text="Scale Y:")
- col.prop(strip, "scale_start_y", text="Start")
- col.prop(strip, "scale_end_y", text="End")
+ col.prop(strip, "uniform_scale")
+
+ if (strip.uniform_scale):
+ col = layout.column(align=True)
+ col.label(text="Scale:")
+ col.prop(strip, "scale_start_x", text="Start")
+ col.prop(strip, "scale_end_x", text="End")
+ else:
+ col = layout.column(align=True)
+ col.label(text="Scale X:")
+ col.prop(strip, "scale_start_x", text="Start")
+ col.prop(strip, "scale_end_x", text="End")
+
+ col = layout.column(align=True)
+ col.label(text="Scale Y:")
+ col.prop(strip, "scale_start_y", text="Start")
+ col.prop(strip, "scale_end_y", text="End")
layout.separator()
@@ -420,10 +429,11 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel):
col = layout.column(align=True)
if strip.type == 'SPEED':
col.prop(strip, "speed_fader", text="Speed fader")
- else:
- col.prop(strip, "use_effect_default_fade", "Default fade")
- if not strip.use_effect_default_fade:
- col.prop(strip, "effect_fader", text="Effect fader")
+ elif strip.type in ('CROSS', 'GAMMA_CROSS', 'PLUGIN', 'WIPE',
+ 'TRANSFORM'):
+ col.prop(strip, "use_effect_default_fade", "Default fade")
+ if not strip.use_effect_default_fade:
+ col.prop(strip, "effect_fader", text="Effect fader")
class SEQUENCER_PT_input(SequencerButtonsPanel):
@@ -507,9 +517,9 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel):
row = layout.row()
if strip.sound.packed_file:
- row.operator("sound.unpack", icon='ICON_PACKAGE', text="Unpack")
+ row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
else:
- row.operator("sound.pack", icon='ICON_UGLYPACKAGE', text="Pack")
+ row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
row.prop(strip.sound, "caching")
diff --git a/release/scripts/ui/space_text.py b/release/scripts/ui/space_text.py
index 95175e9ce41..5df937aacde 100644
--- a/release/scripts/ui/space_text.py
+++ b/release/scripts/ui/space_text.py
@@ -42,7 +42,7 @@ class TEXT_HT_header(bpy.types.Header):
if text and text.modified:
row = layout.row()
# row.color(redalert)
- row.operator("text.resolve_conflict", text="", icon='ICON_HELP')
+ row.operator("text.resolve_conflict", text="", icon='HELP')
layout.template_ID(st, "text", new="text.new", unlink="text.unlink")
@@ -104,14 +104,14 @@ class TEXT_PT_find(bpy.types.Panel):
col = layout.column(align=True)
row = col.row()
row.prop(st, "find_text", text="")
- row.operator("text.find_set_selected", text="", icon='ICON_TEXT')
+ row.operator("text.find_set_selected", text="", icon='TEXT')
col.operator("text.find")
# replace
col = layout.column(align=True)
row = col.row()
row.prop(st, "replace_text", text="")
- row.operator("text.replace_set_selected", text="", icon='ICON_TEXT')
+ row.operator("text.replace_set_selected", text="", icon='TEXT')
col.operator("text.replace")
# mark
@@ -156,7 +156,7 @@ class TEXT_MT_text(bpy.types.Menu):
layout.separator()
- layout.operator("text.properties", icon='ICON_MENU_PANEL')
+ layout.operator("text.properties", icon='MENU_PANEL')
layout.menu("TEXT_MT_templates")
diff --git a/release/scripts/ui/space_time.py b/release/scripts/ui/space_time.py
index 4c1111cee47..86347f8c543 100644
--- a/release/scripts/ui/space_time.py
+++ b/release/scripts/ui/space_time.py
@@ -54,32 +54,32 @@ class TIME_HT_header(bpy.types.Header):
layout.separator()
row = layout.row(align=True)
- row.operator("screen.frame_jump", text="", icon='ICON_REW').end = False
- row.operator("screen.keyframe_jump", text="", icon='ICON_PREV_KEYFRAME').next = False
+ row.operator("screen.frame_jump", text="", icon='REW').end = False
+ row.operator("screen.keyframe_jump", text="", icon='PREV_KEYFRAME').next = False
if not screen.animation_playing:
- row.operator("screen.animation_play", text="", icon='ICON_PLAY_REVERSE').reverse = True
- row.operator("screen.animation_play", text="", icon='ICON_PLAY')
+ row.operator("screen.animation_play", text="", icon='PLAY_REVERSE').reverse = True
+ row.operator("screen.animation_play", text="", icon='PLAY')
else:
sub = row.row()
sub.scale_x = 2.0
- sub.operator("screen.animation_play", text="", icon='ICON_PAUSE')
- row.operator("screen.keyframe_jump", text="", icon='ICON_NEXT_KEYFRAME').next = True
- row.operator("screen.frame_jump", text="", icon='ICON_FF').end = True
+ sub.operator("screen.animation_play", text="", icon='PAUSE')
+ row.operator("screen.keyframe_jump", text="", icon='NEXT_KEYFRAME').next = True
+ row.operator("screen.frame_jump", text="", icon='FF').end = True
row = layout.row(align=True)
- row.prop(tools, "enable_auto_key", text="", toggle=True, icon='ICON_REC')
+ row.prop(tools, "enable_auto_key", text="", toggle=True, icon='REC')
if screen.animation_playing and tools.enable_auto_key:
subsub = row.row()
subsub.prop(tools, "record_with_nla", toggle=True)
- layout.prop(scene, "sync_audio", text="Realtime", toggle=True, icon='ICON_SPEAKER')
+ layout.prop(scene, "sync_audio", text="Realtime", toggle=True, icon='SPEAKER')
layout.separator()
row = layout.row(align=True)
row.prop_object(scene, "active_keying_set", scene, "keying_sets", text="")
- row.operator("anim.keyframe_insert", text="", icon='ICON_KEY_HLT')
- row.operator("anim.keyframe_delete", text="", icon='ICON_KEY_DEHLT')
+ row.operator("anim.keyframe_insert", text="", icon='KEY_HLT')
+ row.operator("anim.keyframe_delete", text="", icon='KEY_DEHLT')
class TIME_MT_view(bpy.types.Menu):
@@ -95,6 +95,7 @@ class TIME_MT_view(bpy.types.Menu):
layout.separator()
+ layout.prop(st, "show_cframe_indicator")
layout.prop(st, "only_selected")
@@ -142,11 +143,7 @@ class TIME_MT_playback(bpy.types.Menu):
layout.separator()
- layout.prop(st, "continue_physics")
-
- layout.separator()
-
- layout.prop(scene, "sync_audio", text="Realtime Playback", icon='ICON_SPEAKER')
+ layout.prop(scene, "sync_audio", text="Realtime Playback", icon='SPEAKER')
layout.prop(scene, "mute_audio")
layout.prop(scene, "scrub_audio")
diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py
index bf232116bb6..383e7ce4e9c 100644
--- a/release/scripts/ui/space_userpref.py
+++ b/release/scripts/ui/space_userpref.py
@@ -1083,6 +1083,7 @@ class USERPREF_PT_file(bpy.types.Panel):
sub.label(text="Scripts:")
sub.label(text="Sounds:")
sub.label(text="Temp:")
+ sub.label(text="Animation Player:")
sub = col1.column()
sub.prop(paths, "fonts_directory", text="")
@@ -1093,6 +1094,9 @@ class USERPREF_PT_file(bpy.types.Panel):
sub.prop(paths, "python_scripts_directory", text="")
sub.prop(paths, "sounds_directory", text="")
sub.prop(paths, "temporary_directory", text="")
+ subsplit = sub.split(percentage=0.3)
+ subsplit.prop(paths, "animation_player_preset", text="")
+ subsplit.prop(paths, "animation_player", text="")
col = split.column()
col.label(text="Save & Load:")
@@ -1186,6 +1190,12 @@ class USERPREF_PT_input(bpy.types.Panel):
sub.prop(inputs, "ndof_pan_speed", text="Pan Speed")
sub.prop(inputs, "ndof_rotate_speed", text="Orbit Speed")
+ col.separator()
+
+ sub = col.column()
+ sub.label(text="Double Click:")
+ sub.prop(inputs, "double_click_time", text="Speed")
+
row.separator()
# Keymap Settings
@@ -1215,16 +1225,16 @@ class USERPREF_PT_input(bpy.types.Panel):
row = subcol.row()
if kmi.expanded:
- row.prop(kmi, "expanded", text="", icon='ICON_TRIA_DOWN')
+ row.prop(kmi, "expanded", text="", icon='TRIA_DOWN')
else:
- row.prop(kmi, "expanded", text="", icon='ICON_TRIA_RIGHT')
+ row.prop(kmi, "expanded", text="", icon='TRIA_RIGHT')
itemrow = row.row()
itemrow.enabled = km.user_defined
if kmi.active:
- itemrow.prop(kmi, "active", text="", icon='ICON_CHECKBOX_HLT')
+ itemrow.prop(kmi, "active", text="", icon='CHECKBOX_HLT')
else:
- itemrow.prop(kmi, "active", text="", icon='ICON_CHECKBOX_DEHLT')
+ itemrow.prop(kmi, "active", text="", icon='CHECKBOX_DEHLT')
itemcol = itemrow.column()
itemcol.active = kmi.active
@@ -1286,11 +1296,11 @@ class USERPREF_PT_input(bpy.types.Panel):
itemcol.separator()
- itemrow.operator("wm.keyitem_remove", text="", icon='ICON_ZOOMOUT')
+ itemrow.operator("wm.keyitem_remove", text="", icon='ZOOMOUT')
itemrow = col.row()
itemrow.label()
- itemrow.operator("wm.keyitem_add", text="", icon='ICON_ZOOMIN')
+ itemrow.operator("wm.keyitem_add", text="", icon='ZOOMIN')
itemrow.enabled = km.user_defined
bpy.types.register(USERPREF_HT_header)
diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py
index 8fdba45e340..c8f10d692b4 100644
--- a/release/scripts/ui/space_view3d.py
+++ b/release/scripts/ui/space_view3d.py
@@ -87,16 +87,16 @@ class VIEW3D_HT_header(bpy.types.Header):
# OpenGL render
row = layout.row(align=True)
- row.operator("screen.opengl_render", text="", icon='ICON_RENDER_STILL')
- props = row.operator("screen.opengl_render", text="", icon='ICON_RENDER_ANIMATION')
+ row.operator("screen.opengl_render", text="", icon='RENDER_STILL')
+ props = row.operator("screen.opengl_render", text="", icon='RENDER_ANIMATION')
props.animation = True
# Pose
if obj and obj.mode == 'POSE':
row = layout.row(align=True)
- row.operator("pose.copy", text="", icon='ICON_COPYDOWN')
- row.operator("pose.paste", text="", icon='ICON_PASTEDOWN')
- props = row.operator("pose.paste", text="", icon='ICON_PASTEFLIPDOWN')
+ row.operator("pose.copy", text="", icon='COPYDOWN')
+ row.operator("pose.paste", text="", icon='PASTEDOWN')
+ props = row.operator("pose.paste", text="", icon='PASTEFLIPDOWN')
props.flipped = 1
@@ -124,24 +124,24 @@ class VIEW3D_MT_transform(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.operator("tfm.translate", text="Grab/Move")
+ layout.operator("transform.translate", text="Grab/Move")
# TODO: sub-menu for grab per axis
- layout.operator("tfm.rotate", text="Rotate")
+ layout.operator("transform.rotate", text="Rotate")
# TODO: sub-menu for rot per axis
- layout.operator("tfm.resize", text="Scale")
+ layout.operator("transform.resize", text="Scale")
# TODO: sub-menu for scale per axis
layout.separator()
- layout.operator("tfm.tosphere", text="To Sphere")
- layout.operator("tfm.shear", text="Shear")
- layout.operator("tfm.warp", text="Warp")
- layout.operator("tfm.transform", text="Push/Pull").mode = 'PUSHPULL'
+ layout.operator("transform.tosphere", text="To Sphere")
+ layout.operator("transform.shear", text="Shear")
+ layout.operator("transform.warp", text="Warp")
+ layout.operator("transform.transform", text="Push/Pull").mode = 'PUSHPULL'
if context.edit_object and context.edit_object.type == 'ARMATURE':
layout.operator("armature.align")
else:
layout.operator_context = 'EXEC_REGION_WIN'
- layout.operator("tfm.transform", text="Align to Transform Orientation").mode = 'ALIGN' # XXX see alignmenu() in edit.c of b2.4x to get this working
+ layout.operator("transform.transform", text="Align to Transform Orientation").mode = 'ALIGN' # XXX see alignmenu() in edit.c of b2.4x to get this working
layout.separator()
@@ -158,32 +158,32 @@ class VIEW3D_MT_mirror(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.operator("tfm.mirror", text="Interactive Mirror")
+ layout.operator("transform.mirror", text="Interactive Mirror")
layout.separator()
layout.operator_context = 'INVOKE_REGION_WIN'
- props = layout.operator("tfm.mirror", text="X Global")
+ props = layout.operator("transform.mirror", text="X Global")
props.constraint_axis = (True, False, False)
props.constraint_orientation = 'GLOBAL'
- props = layout.operator("tfm.mirror", text="Y Global")
+ props = layout.operator("transform.mirror", text="Y Global")
props.constraint_axis = (False, True, False)
props.constraint_orientation = 'GLOBAL'
- props = layout.operator("tfm.mirror", text="Z Global")
+ props = layout.operator("transform.mirror", text="Z Global")
props.constraint_axis = (False, False, True)
props.constraint_orientation = 'GLOBAL'
if context.edit_object:
layout.separator()
- props = layout.operator("tfm.mirror", text="X Local")
+ props = layout.operator("transform.mirror", text="X Local")
props.constraint_axis = (True, False, False)
props.constraint_orientation = 'LOCAL'
- props = layout.operator("tfm.mirror", text="Y Local")
+ props = layout.operator("transform.mirror", text="Y Local")
props.constraint_axis = (False, True, False)
props.constraint_orientation = 'LOCAL'
- props = layout.operator("tfm.mirror", text="Z Local")
+ props = layout.operator("transform.mirror", text="Z Local")
props.constraint_axis = (False, False, True)
props.constraint_orientation = 'LOCAL'
@@ -230,8 +230,8 @@ class VIEW3D_MT_view(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.operator("view3d.properties", icon='ICON_MENU_PANEL')
- layout.operator("view3d.toolbar", icon='ICON_MENU_PANEL')
+ layout.operator("view3d.properties", icon='MENU_PANEL')
+ layout.operator("view3d.toolbar", icon='MENU_PANEL')
layout.separator()
@@ -918,7 +918,7 @@ class VIEW3D_MT_pose(bpy.types.Menu):
layout.menu("VIEW3D_MT_transform")
layout.menu("VIEW3D_MT_snap")
if arm.drawtype in ('BBONE', 'ENVELOPE'):
- layout.operator("tfm.transform", text="Scale Envelope Distance").mode = 'BONESIZE'
+ layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONESIZE'
layout.menu("VIEW3D_MT_pose_transform")
@@ -1177,7 +1177,7 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
layout.separator()
- layout.operator("TFM_OT_edge_slide", text="Edge Slide")
+ layout.operator("TRANSFORM_OT_edge_slide", text="Edge Slide")
layout.operator("mesh.loop_multi_select", text="Edge Loop")
# uiItemO(layout, "Loopcut", 0, "mesh.loop_cut"); // CutEdgeloop(em, 1);
@@ -1298,7 +1298,7 @@ class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu):
edit_object = context.edit_object
if edit_object.type == 'CURVE':
- layout.operator("tfm.transform").mode = 'TILT'
+ layout.operator("transform.transform").mode = 'TILT'
layout.operator("curve.tilt_clear")
layout.operator("curve.separate")
@@ -1458,9 +1458,9 @@ class VIEW3D_MT_edit_armature(bpy.types.Menu):
layout.menu("VIEW3D_MT_edit_armature_roll")
if arm.drawtype == 'ENVELOPE':
- layout.operator("tfm.transform", text="Scale Envelope Distance").mode = 'BONESIZE'
+ layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONESIZE'
else:
- layout.operator("tfm.transform", text="Scale B-Bone Width").mode = 'BONESIZE'
+ layout.operator("transform.transform", text="Scale B-Bone Width").mode = 'BONESIZE'
layout.separator()
@@ -1544,7 +1544,7 @@ class VIEW3D_MT_edit_armature_roll(bpy.types.Menu):
layout.separator()
- layout.operator("tfm.transform", text="Set Roll").mode = 'BONE_ROLL'
+ layout.operator("transform.transform", text="Set Roll").mode = 'BONE_ROLL'
# ********** Panel **********
@@ -1598,14 +1598,14 @@ class VIEW3D_PT_3dview_name(bpy.types.Panel):
ob = context.active_object
row = layout.row()
- row.label(text="", icon='ICON_OBJECT_DATA')
+ row.label(text="", icon='OBJECT_DATA')
row.prop(ob, "name", text="")
if ob.type == 'ARMATURE' and ob.mode in ('EDIT', 'POSE'):
bone = context.active_bone
if bone:
row = layout.row()
- row.label(text="", icon='ICON_BONE_DATA')
+ row.label(text="", icon='BONE_DATA')
row.prop(bone, "name", text="")
@@ -1773,13 +1773,13 @@ class VIEW3D_PT_transform_orientations(bpy.types.Panel):
col = layout.column()
col.prop(view, "transform_orientation")
- col.operator("tfm.create_orientation", text="Create")
+ col.operator("transform.create_orientation", text="Create")
orientation = view.current_orientation
if orientation:
col.prop(orientation, "name")
- col.operator("tfm.delete_orientation", text="Delete")
+ col.operator("transform.delete_orientation", text="Delete")
class VIEW3D_PT_etch_a_ton(bpy.types.Panel):
diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py
index e9dfe3ffd94..2c959e640ea 100644
--- a/release/scripts/ui/space_view3d_toolbar.py
+++ b/release/scripts/ui/space_view3d_toolbar.py
@@ -37,9 +37,9 @@ class VIEW3D_PT_tools_objectmode(View3DPanel):
col = layout.column(align=True)
col.label(text="Transform:")
- col.operator("tfm.translate")
- col.operator("tfm.rotate")
- col.operator("tfm.resize", text="Scale")
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
col = layout.column(align=True)
col.label(text="Object:")
@@ -84,15 +84,15 @@ class VIEW3D_PT_tools_meshedit(View3DPanel):
col = layout.column(align=True)
col.label(text="Transform:")
- col.operator("tfm.translate")
- col.operator("tfm.rotate")
- col.operator("tfm.resize", text="Scale")
- col.operator("tfm.shrink_fatten", text="Along Normal")
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
+ col.operator("transform.shrink_fatten", text="Along Normal")
col = layout.column(align=True)
col.label(text="Deform:")
- col.operator("tfm.edge_slide")
+ col.operator("transform.edge_slide")
col.operator("mesh.rip_move")
col.operator("mesh.vertices_smooth")
@@ -168,13 +168,13 @@ class VIEW3D_PT_tools_curveedit(View3DPanel):
col = layout.column(align=True)
col.label(text="Transform:")
- col.operator("tfm.translate")
- col.operator("tfm.rotate")
- col.operator("tfm.resize", text="Scale")
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
col = layout.column(align=True)
- col.operator("tfm.transform", text="Tilt").mode = 'TILT'
- col.operator("tfm.transform", text="Shrink/Fatten").mode = 'CURVE_SHRINKFATTEN'
+ col.operator("transform.transform", text="Tilt").mode = 'TILT'
+ col.operator("transform.transform", text="Shrink/Fatten").mode = 'CURVE_SHRINKFATTEN'
col = layout.column(align=True)
col.label(text="Curve:")
@@ -222,9 +222,9 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel):
col = layout.column(align=True)
col.label(text="Transform:")
- col.operator("tfm.translate")
- col.operator("tfm.rotate")
- col.operator("tfm.resize", text="Scale")
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
col = layout.column(align=True)
col.label(text="Curve:")
@@ -295,9 +295,9 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel):
col = layout.column(align=True)
col.label(text="Transform:")
- col.operator("tfm.translate")
- col.operator("tfm.rotate")
- col.operator("tfm.resize", text="Scale")
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
col = layout.column(align=True)
col.label(text="Bones:")
@@ -347,9 +347,9 @@ class VIEW3D_PT_tools_mballedit(View3DPanel):
col = layout.column(align=True)
col.label(text="Transform:")
- col.operator("tfm.translate")
- col.operator("tfm.rotate")
- col.operator("tfm.resize", text="Scale")
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
col = layout.column(align=True)
col.label(text="Repeat:")
@@ -375,9 +375,9 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel):
col = layout.column(align=True)
col.label(text="Transform:")
- col.operator("tfm.translate")
- col.operator("tfm.rotate")
- col.operator("tfm.resize", text="Scale")
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
col = layout.column(align=True)
col.operator("lattice.make_regular")
@@ -407,9 +407,9 @@ class VIEW3D_PT_tools_posemode(View3DPanel):
col = layout.column(align=True)
col.label(text="Transform:")
- col.operator("tfm.translate")
- col.operator("tfm.rotate")
- col.operator("tfm.resize", text="Scale")
+ col.operator("transform.translate")
+ col.operator("transform.rotate")
+ col.operator("transform.resize", text="Scale")
col = layout.column(align=True)
col.label(text="In-Between:")