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:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2009-10-06 05:58:22 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2009-10-06 05:58:22 +0400
commit63a88075b574e8f2f9adc041f423f49a7356d736 (patch)
tree951f1f65d74d052debdafa14f6ad22750b6aad04 /release
parent11bdf6ea10ee7bc5e2862cdddbf42eddb06c42fa (diff)
parent69a24325742c617a9902376b061006dfb24f0a3c (diff)
svn merge -r 23528:23646 https://svn.blender.org/svnroot/bf-blender/trunk/blendersoc-2009-jaguarandi
Diffstat (limited to 'release')
-rw-r--r--release/scripts/io/export_3ds.py22
-rw-r--r--release/scripts/io/export_fbx.py28
-rw-r--r--release/scripts/io/export_obj.py31
-rw-r--r--release/scripts/io/export_x3d.py13
-rw-r--r--release/scripts/io/import_3ds.py7
-rw-r--r--release/scripts/io/import_obj.py19
-rw-r--r--release/scripts/io/netrender/client.py4
-rw-r--r--release/scripts/io/netrender/master.py40
-rw-r--r--release/scripts/io/netrender/master_html.py13
-rw-r--r--release/scripts/io/netrender/model.py22
-rw-r--r--release/scripts/io/netrender/slave.py71
-rw-r--r--release/scripts/modules/bpy_ops.py17
-rw-r--r--release/scripts/ui/buttons_data_bone.py210
-rw-r--r--release/scripts/ui/buttons_data_lamp.py6
-rw-r--r--release/scripts/ui/buttons_material.py70
-rw-r--r--release/scripts/ui/buttons_object.py4
-rw-r--r--release/scripts/ui/buttons_object_constraint.py141
-rw-r--r--release/scripts/ui/buttons_particle.py268
-rw-r--r--release/scripts/ui/buttons_physics_cloth.py38
-rw-r--r--release/scripts/ui/buttons_physics_common.py154
-rw-r--r--release/scripts/ui/buttons_physics_field.py114
-rw-r--r--release/scripts/ui/buttons_physics_softbody.py17
-rw-r--r--release/scripts/ui/buttons_scene.py106
-rw-r--r--release/scripts/ui/buttons_texture.py21
-rw-r--r--release/scripts/ui/space_info.py4
-rw-r--r--release/scripts/ui/space_userpref.py1
-rw-r--r--release/scripts/ui/space_view3d.py21
27 files changed, 925 insertions, 537 deletions
diff --git a/release/scripts/io/export_3ds.py b/release/scripts/io/export_3ds.py
index 19c12146769..2c1999c3d45 100644
--- a/release/scripts/io/export_3ds.py
+++ b/release/scripts/io/export_3ds.py
@@ -559,14 +559,15 @@ def extract_triangles(mesh):
uf = mesh.active_uv_texture.data[i] if do_uv else None
if do_uv:
- f_uv = (uf.uv1, uf.uv2, uf.uv3, uf.uv4) if face.verts[3] else (uf.uv1, uf.uv2, uf.uv3)
+ f_uv = uf.uv
+ # f_uv = (uf.uv1, uf.uv2, uf.uv3, uf.uv4) if face.verts[3] else (uf.uv1, uf.uv2, uf.uv3)
# f_uv = face.uv
img = uf.image if uf else None
# img = face.image
if img: img = img.name
-
- if f_v[3] == 0:
- # if len(f_v)==3:
+
+ # if f_v[3] == 0:
+ if len(f_v)==3:
new_tri = tri_wrapper((f_v[0], f_v[1], f_v[2]), face.material_index, img)
# new_tri = tri_wrapper((f_v[0].index, f_v[1].index, f_v[2].index), face.mat, img)
if (do_uv): new_tri.faceuvs= uv_key(f_uv[0]), uv_key(f_uv[1]), uv_key(f_uv[2])
@@ -916,11 +917,11 @@ def save_3ds(filename, context):
if not filename.lower().endswith('.3ds'):
filename += '.3ds'
-
+
# XXX
# if not BPyMessages.Warning_SaveOver(filename):
# return
-
+
# XXX
time1 = time.clock()
# time1= Blender.sys.time()
@@ -992,7 +993,7 @@ def save_3ds(filename, context):
if mat: mat_name = mat.name
else: mat_name = None
# else there alredy set to none
-
+
img = uf.image
# img = f.image
if img: img_name = img.name
@@ -1016,7 +1017,7 @@ def save_3ds(filename, context):
if free:
free_derived_objects(ob)
-
+
# Make material chunks for all materials used in the meshes:
for mat_and_image in materialDict.values():
object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1]))
@@ -1109,11 +1110,12 @@ class EXPORT_OT_3ds(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
- bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""),
+ # bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""),
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the 3DS file", maxlen= 1024, default= ""),
]
def execute(self, context):
- save_3ds(self.filename, context)
+ save_3ds(self.path, context)
return ('FINISHED',)
def invoke(self, context, event):
diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py
index aa65473b8d6..21b1388ebfe 100644
--- a/release/scripts/io/export_fbx.py
+++ b/release/scripts/io/export_fbx.py
@@ -1211,13 +1211,13 @@ def write(filename, batch_objects = None, \
mat_colamb = world_amb
# mat_colamb = tuple([c for c in world_amb])
- mat_dif = mat.diffuse_reflection
+ mat_dif = mat.diffuse_intensity
# mat_dif = mat.ref
mat_amb = mat.ambient
# mat_amb = mat.amb
mat_hard = (float(mat.specular_hardness)-1)/5.10
# mat_hard = (float(mat.hard)-1)/5.10
- mat_spec = mat.specular_reflection/2.0
+ mat_spec = mat.specular_intensity/2.0
# mat_spec = mat.spec/2.0
mat_alpha = mat.alpha
mat_emit = mat.emit
@@ -1528,7 +1528,8 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tPolygonVertexIndex: ')
i=-1
for f in me.faces:
- fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3]
+ fi = f.verts
+ # fi = [v_index for j, v_index in enumerate(f.verts) if v_index != 0 or j != 3]
# fi = [v.index for v in f]
# flip the last index, odd but it looks like
@@ -1637,10 +1638,7 @@ def write(filename, batch_objects = None, \
# returns a slice of data depending on number of face verts
# data is either a MeshTextureFace or MeshColor
def face_data(data, face):
- if f.verts[3] == 0:
- totvert = 3
- else:
- totvert = 4
+ totvert = len(f.verts)
return data[:totvert]
@@ -1740,12 +1738,9 @@ def write(filename, batch_objects = None, \
i = -1
ii = 0 # Count how many UVs we write
- for f, uf in zip(me.faces, uvlayer.data):
+ for uf in uvlayer.data:
# for f in me.faces:
- uvs = [uf.uv1, uf.uv2, uf.uv3, uf.uv4]
- uvs = face_data(uvs, f)
-
- for uv in uvs:
+ for uv in uf.uv:
# for uv in f.uv:
if i==-1:
file.write('%.6f,%.6f' % tuple(uv))
@@ -3356,7 +3351,8 @@ class EXPORT_OT_fbx(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
- bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default=""),
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the FBX file", maxlen= 1024, default= ""),
+
bpy.props.BoolProperty(attr="EXP_OBS_SELECTED", name="Selected Objects", description="Export selected objects on visible layers", default=True),
# bpy.props.BoolProperty(attr="EXP_OBS_SCENE", name="Scene Objects", description="Export all objects in this scene", default=True),
bpy.props.FloatProperty(attr="_SCALE", 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),
@@ -3389,8 +3385,8 @@ class EXPORT_OT_fbx(bpy.types.Operator):
return context.active_object != None
def execute(self, context):
- if not self.filename:
- raise Exception("filename not set")
+ if not self.path:
+ raise Exception("path not set")
GLOBAL_MATRIX = mtx4_identity
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self._SCALE
@@ -3398,7 +3394,7 @@ class EXPORT_OT_fbx(bpy.types.Operator):
if self._YROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n
if self._ZROT90: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n
- write(self.filename,
+ write(self.path,
None, # XXX
context,
self.EXP_OBS_SELECTED,
diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py
index e2ac78798bd..83b400816e3 100644
--- a/release/scripts/io/export_obj.py
+++ b/release/scripts/io/export_obj.py
@@ -153,7 +153,7 @@ def write_mtl(scene, filename, copy_images):
elif mat: # No face image. if we havea material search for MTex image.
for mtex in mat.textures:
- if mtex and mtex.texure.type == 'IMAGE':
+ if mtex and mtex.texture.type == 'IMAGE':
try:
filename = copy_image(mtex.texture.image)
# filename = mtex.texture.image.filename.split('\\')[-1].split('/')[-1]
@@ -330,7 +330,8 @@ def write(filename, objects, scene,
return round(v.x, 6), round(v.y, 6), round(v.z, 6)
def veckey2d(v):
- return round(v.x, 6), round(v.y, 6)
+ return round(v[0], 6), round(v[1], 6)
+ # return round(v.x, 6), round(v.y, 6)
def findVertexGroupName(face, vWeightMap):
"""
@@ -376,7 +377,7 @@ def write(filename, objects, scene,
# scn = Scene.GetCurrent()
file = open(filename, "w")
-
+
# Write Header
version = "2.5"
file.write('# Blender3D v%s OBJ File: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] ))
@@ -593,11 +594,12 @@ def write(filename, objects, scene,
tface = uv_layer.data[f_index]
- uvs = [tface.uv1, tface.uv2, tface.uv3]
+ uvs = tface.uv
+ # uvs = [tface.uv1, tface.uv2, tface.uv3]
- # add another UV if it's a quad
- if f.verts[3] != 0:
- uvs.append(tface.uv4)
+ # # add another UV if it's a quad
+ # if len(f.verts) == 4:
+ # uvs.append(tface.uv4)
for uv_index, uv in enumerate(uvs):
uvkey = veckey2d(uv)
@@ -661,8 +663,8 @@ def write(filename, objects, scene,
for f_index, f in enumerate(faces):
f_v = [{"index": index, "vertex": me.verts[index]} for index in f.verts]
- if f.verts[3] == 0:
- f_v.pop()
+ # if f.verts[3] == 0:
+ # f_v.pop()
# f_v= f.v
f_smooth= f.smooth
@@ -673,9 +675,10 @@ def write(filename, objects, scene,
tface = me.active_uv_texture.data[face_index_pairs[f_index][1]]
f_image = tface.image
- f_uv= [tface.uv1, tface.uv2, tface.uv3]
- if f.verts[3] != 0:
- f_uv.append(tface.uv4)
+ f_uv = tface.uv
+ # f_uv= [tface.uv1, tface.uv2, tface.uv3]
+ # if len(f.verts) == 4:
+ # f_uv.append(tface.uv4)
# f_image = f.image
# f_uv= f.uv
@@ -918,7 +921,7 @@ class EXPORT_OT_obj(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
- bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the OBJ file", maxlen= 1024, default= ""),
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the OBJ file", maxlen= 1024, default= ""),
# context group
bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False),
@@ -949,7 +952,7 @@ class EXPORT_OT_obj(bpy.types.Operator):
def execute(self, context):
- do_export(self.filename, context,
+ do_export(self.path, context,
EXPORT_TRI=self.use_triangles,
EXPORT_EDGES=self.use_edges,
EXPORT_NORMALS=self.use_normals,
diff --git a/release/scripts/io/export_x3d.py b/release/scripts/io/export_x3d.py
index f23ccf8d2dc..db29afc7d6d 100644
--- a/release/scripts/io/export_x3d.py
+++ b/release/scripts/io/export_x3d.py
@@ -604,7 +604,8 @@ class x3d_class:
for face in mesh.active_uv_texture.data:
# for face in mesh.faces:
- uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
+ uvs = face.uv
+ # uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
for uv in uvs:
# for uv in face.uv:
@@ -676,11 +677,11 @@ class x3d_class:
shininess = mat.specular_hardness/512.0
# shininess = mat.hard/512.0
- specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_reflection+0.001))
+ specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_intensity+0.001))
# specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001))
- specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_reflection+0.001))
+ specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_intensity+0.001))
# specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001))
- specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_reflection+0.001))
+ specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_intensity+0.001))
# specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001))
transp = 1-mat.alpha
# matFlags = mat.getMode()
@@ -1213,7 +1214,7 @@ class EXPORT_OT_x3d(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
- bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen=1024, default=""),
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the X3D file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="apply_modifiers", name="Apply Modifiers", description="Use transformed mesh data from each object.", default=True),
bpy.props.BoolProperty(attr="triangulate", name="Triangulate", description="Triangulate quads.", default=False),
@@ -1221,7 +1222,7 @@ class EXPORT_OT_x3d(bpy.types.Operator):
]
def execute(self, context):
- x3d_export(self.filename, context, self.apply_modifiers, self.triangulate, self.compress)
+ x3d_export(self.path, context, self.apply_modifiers, self.triangulate, self.compress)
return ('FINISHED',)
def invoke(self, context, event):
diff --git a/release/scripts/io/import_3ds.py b/release/scripts/io/import_3ds.py
index 99825471764..339fac839ea 100644
--- a/release/scripts/io/import_3ds.py
+++ b/release/scripts/io/import_3ds.py
@@ -420,7 +420,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
# bmesh_verts.extend( [myContextMesh_vertls[i] for i in vertsToUse] )
# +1 because of DUMMYVERT
- bmesh.faces.foreach_set("verts", unpack_face_list([[myVertMapping[vindex] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces]))
+ bmesh.faces.foreach_set("verts_raw", unpack_face_list([[myVertMapping[vindex] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces]))
# face_mapping = bmesh.faces.extend( [ [ bmesh_verts[ myVertMapping[vindex]+1] for vindex in myContextMesh_facels[fIdx]] for fIdx in faces ], indexList=True )
if bmesh.faces and (contextMeshUV or img):
@@ -1140,14 +1140,15 @@ class IMPORT_OT_3ds(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
- bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for importing the 3DS file", maxlen=1024, default= ""),
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for importing the 3DS file", maxlen= 1024, default= ""),
+
# bpy.props.FloatProperty(attr="size_constraint", name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0),
# bpy.props.BoolProperty(attr="search_images", name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
# bpy.props.BoolProperty(attr="apply_matrix", name="Transform Fix", description="Workaround for object transformations importing incorrectly", default=False),
]
def execute(self, context):
- load_3ds(self.filename, context, 0.0, False, False)
+ load_3ds(self.path, context, 0.0, False, False)
return ('FINISHED',)
def invoke(self, context, event):
diff --git a/release/scripts/io/import_obj.py b/release/scripts/io/import_obj.py
index 9a00dc1cc2a..a762005ae7d 100644
--- a/release/scripts/io/import_obj.py
+++ b/release/scripts/io/import_obj.py
@@ -87,11 +87,19 @@ def unpack_face_list(list_of_tuples):
l = []
for t in list_of_tuples:
face = [i for i in t]
+
if len(face) != 3 and len(face) != 4:
raise RuntimeError("{0} vertices in face.".format(len(face)))
+
+ # rotate indices if the 4th is 0
+ if len(face) == 4 and face[3] == 0:
+ face = [face[3], face[0], face[1], face[2]]
+
if len(face) == 3:
face.append(0)
+
l.extend(face)
+
return l
def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
@@ -709,9 +717,9 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
# me.verts.extend(verts_loc)
# faces is a list of (vert_indices, texco_indices, ...) tuples
- # XXX faces should not contain edges
+ # XXX faces should contain either 3 or 4 verts
# XXX no check for valid face indices
- me.faces.foreach_set("verts", unpack_face_list([f[0] for f in faces]))
+ me.faces.foreach_set("verts_raw", unpack_face_list([f[0] for f in faces]))
# face_mapping= me.faces.extend([f[0] for f in faces], indexList=True)
if verts_tex and me.faces:
@@ -1568,7 +1576,7 @@ class IMPORT_OT_obj(bpy.types.Operator):
# to the class instance from the operator settings before calling.
__props__ = [
- bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""),
+ bpy.props.StringProperty(attr="path", name="File Path", description="File path used for importing the OBJ file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="CREATE_SMOOTH_GROUPS", name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True),
bpy.props.BoolProperty(attr="CREATE_FGONS", name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True),
@@ -1592,10 +1600,7 @@ class IMPORT_OT_obj(bpy.types.Operator):
def execute(self, context):
# print("Selected: " + context.active_object.name)
- if not self.filename:
- raise Exception("filename not set")
-
- load_obj(self.filename,
+ load_obj(self.path,
context,
self.CLAMP_SIZE,
self.CREATE_FGONS,
diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py
index 65b2937867f..1897d1fd949 100644
--- a/release/scripts/io/netrender/client.py
+++ b/release/scripts/io/netrender/client.py
@@ -3,12 +3,12 @@ import sys, os, re
import http, http.client, http.server, urllib
import subprocess, shutil, time, hashlib
+import netrender.model
import netrender.slave as slave
import netrender.master as master
from netrender.utils import *
-
-def clientSendJob(conn, scene, anim = False, chunks = 5):
+def clientSendJob(conn, scene, anim = False):
netsettings = scene.network_render
job = netrender.model.RenderJob()
diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py
index a3e186a9cfd..be23fda7a91 100644
--- a/release/scripts/io/netrender/master.py
+++ b/release/scripts/io/netrender/master.py
@@ -42,9 +42,10 @@ class MRenderSlave(netrender.model.RenderSlave):
self.job = None
class MRenderJob(netrender.model.RenderJob):
- def __init__(self, job_id, name, files, chunks = 1, priority = 1, blacklist = []):
+ def __init__(self, job_id, job_type, name, files, chunks = 1, priority = 1, blacklist = []):
super().__init__()
self.id = job_id
+ self.type = job_type
self.name = name
self.files = files
self.frames = []
@@ -53,6 +54,10 @@ class MRenderJob(netrender.model.RenderJob):
self.usage = 0.0
self.blacklist = blacklist
self.last_dispatched = time.time()
+
+ # force one chunk for process jobs
+ if self.type == netrender.model.JOB_PROCESS:
+ self.chunks = 1
# special server properties
self.last_update = 0
@@ -93,8 +98,8 @@ class MRenderJob(netrender.model.RenderJob):
if frame:
frame.log_path = log_path
- def addFrame(self, frame_number):
- frame = MRenderFrame(frame_number)
+ def addFrame(self, frame_number, command):
+ frame = MRenderFrame(frame_number, command)
self.frames.append(frame)
return frame
@@ -114,12 +119,14 @@ class MRenderJob(netrender.model.RenderJob):
return frames
class MRenderFrame(netrender.model.RenderFrame):
- def __init__(self, frame):
+ def __init__(self, frame, command):
super().__init__()
self.number = frame
self.slave = None
self.time = 0
self.status = QUEUED
+ self.command = command
+
self.log_path = None
def reset(self, all):
@@ -368,10 +375,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
job_id = self.server.nextJobID()
- job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
+ 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)
for frame in job_info.frames:
- frame = job.addFrame(frame.number)
+ frame = job.addFrame(frame.number, frame.command)
self.server.addJob(job)
@@ -538,17 +545,18 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
frame = job[job_frame]
if frame:
- if job_result == DONE:
- length = int(self.headers['content-length'])
- buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
- f.write(buf)
- f.close()
+ if job.type == netrender.model.JOB_BLENDER:
+ if job_result == DONE:
+ length = int(self.headers['content-length'])
+ buf = self.rfile.read(length)
+ f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
+ f.write(buf)
+ f.close()
- del buf
- elif job_result == ERROR:
- # blacklist slave on this job on error
- job.blacklist.append(slave.id)
+ del buf
+ elif job_result == ERROR:
+ # blacklist slave on this job on error
+ job.blacklist.append(slave.id)
self.server.stats("", "Receiving result")
diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py
index 6a956a70e9f..545659e8dc4 100644
--- a/release/scripts/io/netrender/master_html.py
+++ b/release/scripts/io/netrender/master_html.py
@@ -32,9 +32,8 @@ def get(handler):
def endTable():
output("</table>")
- handler.send_head(content = "text/html")
-
if handler.path == "/html" or handler.path == "/":
+ handler.send_head(content = "text/html")
output("<html><head><title>NetRender</title></head><body>")
output("<h2>Master</h2>")
@@ -86,6 +85,7 @@ def get(handler):
output("</body></html>")
elif handler.path.startswith("/html/job"):
+ handler.send_head(content = "text/html")
job_id = handler.path[9:]
output("<html><head><title>NetRender</title></head><body>")
@@ -108,10 +108,9 @@ def get(handler):
output("</body></html>")
elif handler.path.startswith("/html/log"):
+ handler.send_head(content = "text/plain")
pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)")
- output("<html><head><title>NetRender</title></head><body>")
-
match = pattern.match(handler.path[9:])
if match:
job_id = match.groups()[0]
@@ -125,12 +124,8 @@ def get(handler):
if frame:
f = open(frame.log_path, 'rb')
- output("<pre>")
-
shutil.copyfileobj(f, handler.wfile)
- output("</pre>")
-
f.close()
else:
output("no such frame")
@@ -138,5 +133,3 @@ def get(handler):
output("no such job")
else:
output("malformed url")
-
- output("</body></html>")
diff --git a/release/scripts/io/netrender/model.py b/release/scripts/io/netrender/model.py
index be97f8d0a81..ca2a42d87f6 100644
--- a/release/scripts/io/netrender/model.py
+++ b/release/scripts/io/netrender/model.py
@@ -72,9 +72,18 @@ class RenderSlave:
return slave
+JOB_BLENDER = 1
+JOB_PROCESS = 2
+
+JOB_TYPES = {
+ JOB_BLENDER: "Blender",
+ JOB_PROCESS: "Process"
+ }
+
class RenderJob:
def __init__(self):
self.id = ""
+ self.type = JOB_BLENDER
self.name = ""
self.files = []
self.frames = []
@@ -87,8 +96,8 @@ class RenderJob:
def addFile(self, file_path, start=-1, end=-1):
self.files.append((file_path, start, end))
- def addFrame(self, frame_number):
- frame = RenderFrame(frame_number)
+ def addFrame(self, frame_number, command = ""):
+ frame = RenderFrame(frame_number, command)
self.frames.append(frame)
return frame
@@ -138,6 +147,7 @@ class RenderJob:
max_frame = max((f.number for f in frames)) if frames else -1
return {
"id": self.id,
+ "type": self.type,
"name": self.name,
"files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])],
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
@@ -155,6 +165,7 @@ class RenderJob:
job = RenderJob()
job.id = data["id"]
+ job.type = data["type"]
job.name = data["name"]
job.files = data["files"]
job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
@@ -167,11 +178,12 @@ class RenderJob:
return job
class RenderFrame:
- def __init__(self, number = 0):
+ def __init__(self, number = 0, command = ""):
self.number = number
self.time = 0
self.status = QUEUED
self.slave = None
+ self.command = command
def statusText(self):
return STATUS_TEXT[self.status]
@@ -181,7 +193,8 @@ class RenderFrame:
"number": self.number,
"time": self.time,
"status": self.status,
- "slave": None if not self.slave else self.slave.serialize()
+ "slave": None if not self.slave else self.slave.serialize(),
+ "command": self.command
}
@staticmethod
@@ -194,5 +207,6 @@ class RenderFrame:
frame.time = data["time"]
frame.status = data["status"]
frame.slave = RenderSlave.materialize(data["slave"])
+ frame.command = data["command"]
return frame
diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py
index 657e31001e0..15ca6faf297 100644
--- a/release/scripts/io/netrender/slave.py
+++ b/release/scripts/io/netrender/slave.py
@@ -99,37 +99,46 @@ def render_slave(engine, scene):
if not os.path.exists(JOB_PREFIX):
os.mkdir(JOB_PREFIX)
- job_path = job.files[0][0] # data in files have format (path, start, end)
- main_path, main_file = os.path.split(job_path)
-
- job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path)
- print("Fullpath", job_full_path)
- print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
- engine.update_stats("", "Render File", main_file, "for job", job.id)
-
- for file_path, start, end in job.files[1:]:
- print("\t", file_path)
- testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path)
-
- frame_args = []
-
- for frame in job.frames:
- print("frame", frame.number)
- frame_args += ["-f", str(frame.number)]
+ if job.type == netrender.model.JOB_BLENDER:
+ job_path = job.files[0][0] # data in files have format (path, start, end)
+ main_path, main_file = os.path.split(job_path)
+
+ job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path)
+ print("Fullpath", job_full_path)
+ print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
+ engine.update_stats("", "Render File", main_file, "for job", job.id)
+
+ for file_path, start, end in job.files[1:]:
+ print("\t", file_path)
+ testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path)
+
# announce log to master
logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames])
conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id})
response = conn.getresponse()
- first_frame = job.frames[0].number
+ first_frame = job.frames[0].number
+
# start render
start_t = time.time()
-
- val = SetErrorMode()
- process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- RestoreErrorMode(val)
+
+ if job.type == netrender.model.JOB_BLENDER:
+ frame_args = []
+
+ for frame in job.frames:
+ print("frame", frame.number)
+ frame_args += ["-f", str(frame.number)]
+
+ val = SetErrorMode()
+ process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ RestoreErrorMode(val)
+ elif job.type == netrender.model.JOB_PROCESS:
+ command = job.frames[0].command
+ val = SetErrorMode()
+ process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ RestoreErrorMode(val)
headers = {"job-id":job.id, "slave-id":slave_id}
@@ -155,6 +164,9 @@ def render_slave(engine, scene):
if testCancel(conn, job.id, first_frame):
cancelled = True
+ # read leftovers if needed
+ stdout += process.stdout.read()
+
if cancelled:
# kill process if needed
if process.poll() == None:
@@ -182,11 +194,16 @@ def render_slave(engine, scene):
headers["job-result"] = str(DONE)
for frame in job.frames:
headers["job-frame"] = str(frame.number)
- # send result back to server
- f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
- conn.request("PUT", "/render", f, headers=headers)
- f.close()
- response = conn.getresponse()
+
+ if job.type == netrender.model.JOB_BLENDER:
+ # send image back to server
+ f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
+ conn.request("PUT", "/render", f, headers=headers)
+ f.close()
+ response = conn.getresponse()
+ elif job.type == netrender.model.JOB_PROCESS:
+ conn.request("PUT", "/render", headers=headers)
+ response = conn.getresponse()
else:
headers["job-result"] = str(ERROR)
for frame in job.frames:
diff --git a/release/scripts/modules/bpy_ops.py b/release/scripts/modules/bpy_ops.py
index 83c2e82bf6c..834a33d305d 100644
--- a/release/scripts/modules/bpy_ops.py
+++ b/release/scripts/modules/bpy_ops.py
@@ -139,3 +139,20 @@ class bpy_ops_submodule_op(object):
import bpy
bpy.ops = bpy_ops()
+
+# TODO, C macro's cant define settings :|
+
+class MESH_OT_delete_edgeloop(bpy.types.Operator):
+ '''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
+ __idname__ = "mesh.delete_edgeloop"
+ __label__ = "Export PLY"
+
+ def execute(self, context):
+ bpy.ops.tfm.edge_slide(value=1.0)
+ bpy.ops.mesh.select_more()
+ bpy.ops.mesh.remove_doubles()
+ return ('FINISHED',)
+
+
+bpy.ops.add(MESH_OT_delete_edgeloop)
+
diff --git a/release/scripts/ui/buttons_data_bone.py b/release/scripts/ui/buttons_data_bone.py
index 5971e4492ce..e8041cc7393 100644
--- a/release/scripts/ui/buttons_data_bone.py
+++ b/release/scripts/ui/buttons_data_bone.py
@@ -48,7 +48,7 @@ class BONE_PT_transform(BoneButtonsPanel):
else:
pchan = ob.pose.pose_channels[context.bone.name]
- layout.itemR(pchan, "rotation_mode")
+
row = layout.row()
col = row.column()
@@ -67,6 +67,8 @@ class BONE_PT_transform(BoneButtonsPanel):
col.itemR(pchan, "rotation_euler", text="Rotation")
row.column().itemR(pchan, "scale")
+
+ layout.itemR(pchan, "rotation_mode")
class BONE_PT_transform_locks(BoneButtonsPanel):
__label__ = "Transform Locks"
@@ -98,8 +100,8 @@ class BONE_PT_transform_locks(BoneButtonsPanel):
row.column().itemR(pchan, "lock_scale")
-class BONE_PT_bone(BoneButtonsPanel):
- __label__ = "Bone"
+class BONE_PT_relations(BoneButtonsPanel):
+ __label__ = "Relations"
def draw(self, context):
layout = self.layout
@@ -115,7 +117,17 @@ class BONE_PT_bone(BoneButtonsPanel):
pchan = ob.pose.pose_channels[context.bone.name]
split = layout.split()
-
+
+ col = split.column()
+ col.itemL(text="Layers:")
+ col.itemR(bone, "layer", text="")
+
+ col.itemS()
+
+ if ob and pchan:
+ col.itemL(text="Bone Group:")
+ col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
+
col = split.column()
col.itemL(text="Parent:")
if context.bone:
@@ -123,119 +135,46 @@ class BONE_PT_bone(BoneButtonsPanel):
else:
col.item_pointerR(bone, "parent", arm, "edit_bones", text="")
- row = col.row()
- row.active = bone.parent != None
- row.itemR(bone, "connected")
+ sub = col.column()
+ sub.active = bone.parent != None
+ sub.itemR(bone, "connected")
+ sub.itemR(bone, "hinge", text="Inherit Rotation")
+ sub.itemR(bone, "inherit_scale", text="Inherit Scale")
+
+
+class BONE_PT_display(BoneButtonsPanel):
+ __label__ = "Display"
+
+ def poll(self, context):
+ return context.bone
+
+ def draw(self, context):
+ layout = self.layout
- col.itemL(text="Layers:")
- col.itemR(bone, "layer", text="")
+ ob = context.object
+ bone = context.bone
+ arm = context.armature
- col = split.column()
- col.itemL(text="Inherit:")
- col.itemR(bone, "hinge", text="Rotation")
- col.itemR(bone, "inherit_scale", text="Scale")
- col.itemL(text="Display:")
- col.itemR(bone, "draw_wire", text="Wireframe")
- col.itemR(bone, "hidden", text="Hide")
+ if not bone:
+ bone = context.edit_bone
+ pchan = None
+ else:
+ pchan = ob.pose.pose_channels[context.bone.name]
if ob and pchan:
- split = layout.split()
+ split = layout.split()
+
col = split.column()
- col.itemL(text="Bone Group:")
- col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
+
+ col.itemR(bone, "draw_wire", text="Wireframe")
+ col.itemR(bone, "hidden", text="Hide")
col = split.column()
+
col.itemL(text="Custom Shape:")
col.itemR(pchan, "custom_shape", text="")
-class BONE_PT_inverse_kinematics(BoneButtonsPanel):
- __label__ = "Inverse Kinematics"
- __default_closed__ = True
-
- def poll(self, context):
- ob = context.object
- bone = context.bone
-
- if ob and context.bone:
- pchan = ob.pose.pose_channels[context.bone.name]
- return pchan.has_ik
-
- return False
-
- def draw(self, context):
- layout = self.layout
-
- ob = context.object
- bone = context.bone
- pchan = ob.pose.pose_channels[context.bone.name]
-
- row = layout.row()
- row.itemR(ob.pose, "ik_solver")
-
- split = layout.split(percentage=0.25)
- split.itemR(pchan, "ik_dof_x", text="X")
- row = split.row()
- row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
- row.active = pchan.ik_dof_x
-
- split = layout.split(percentage=0.25)
- row = split.row()
- row.itemR(pchan, "ik_limit_x", text="Limit")
- row.active = pchan.ik_dof_x
- row = split.row(align=True)
- row.itemR(pchan, "ik_min_x", text="")
- row.itemR(pchan, "ik_max_x", text="")
- row.active = pchan.ik_dof_x and pchan.ik_limit_x
-
- split = layout.split(percentage=0.25)
- split.itemR(pchan, "ik_dof_y", text="Y")
- row = split.row()
- row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
- row.active = pchan.ik_dof_y
-
- split = layout.split(percentage=0.25)
- row = split.row()
- row.itemR(pchan, "ik_limit_y", text="Limit")
- row.active = pchan.ik_dof_y
- row = split.row(align=True)
- row.itemR(pchan, "ik_min_y", text="")
- row.itemR(pchan, "ik_max_y", text="")
- row.active = pchan.ik_dof_y and pchan.ik_limit_y
-
- split = layout.split(percentage=0.25)
- split.itemR(pchan, "ik_dof_z", text="Z")
- row = split.row()
- row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
- row.active = pchan.ik_dof_z
-
- split = layout.split(percentage=0.25)
- row = split.row()
- row.itemR(pchan, "ik_limit_z", text="Limit")
- row.active = pchan.ik_dof_z
- row = split.row(align=True)
- row.itemR(pchan, "ik_min_z", text="")
- row.itemR(pchan, "ik_max_z", text="")
- row.active = pchan.ik_dof_z and pchan.ik_limit_z
- split = layout.split()
- split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
- split.itemL()
-
- if ob.pose.ik_solver == "ITASC":
- layout.itemL(text="Joint constraint:")
- split = layout.split(percentage=0.3)
- row = split.row()
- row.itemR(pchan, "ik_rot_control", text="Rotation")
- row = split.row()
- row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
- row.active = pchan.ik_rot_control
- # not supported yet
- #split = layout.split(percentage=0.3)
- #row = split.row()
- #row.itemR(pchan, "ik_lin_control", text="Size")
- #row = split.row()
- #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
- #row.active = pchan.ik_lin_control
class BONE_PT_deform(BoneButtonsPanel):
__label__ = "Deform"
@@ -285,65 +224,10 @@ class BONE_PT_deform(BoneButtonsPanel):
col.itemL(text="Offset:")
col.itemR(bone, "cyclic_offset")
-class BONE_PT_iksolver_itasc(BoneButtonsPanel):
- __idname__ = "BONE_PT_iksolver_itasc"
- __label__ = "iTaSC parameters"
- __default_closed__ = True
-
- def poll(self, context):
- ob = context.object
- bone = context.bone
-
- if ob and context.bone:
- pchan = ob.pose.pose_channels[context.bone.name]
- return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
-
- return False
-
- def draw(self, context):
- layout = self.layout
-
- ob = context.object
- itasc = ob.pose.ik_param
-
- layout.row().itemR(itasc, "simulation")
- if itasc.simulation:
- split = layout.split()
- row = split.row()
- row.itemR(itasc, "reiteration")
- row = split.row()
- if itasc.reiteration:
- itasc.initial_reiteration = True
- row.itemR(itasc, "initial_reiteration")
- row.active = not itasc.reiteration
-
- flow = layout.column_flow()
- flow.itemR(itasc, "precision")
- flow.itemR(itasc, "num_iter")
- flow.active = not itasc.simulation or itasc.initial_reiteration or itasc.reiteration
-
- if itasc.simulation:
- layout.itemR(itasc, "auto_step")
- row = layout.row()
- if itasc.auto_step:
- row.itemR(itasc, "min_step")
- row.itemR(itasc, "max_step")
- else:
- row.itemR(itasc, "num_step")
-
- layout.itemR(itasc, "solver")
- if itasc.simulation:
- layout.itemR(itasc, "feedback")
- layout.itemR(itasc, "max_velocity")
- if itasc.solver == "DLS":
- row = layout.row()
- row.itemR(itasc, "dampmax")
- row.itemR(itasc, "dampeps")
bpy.types.register(BONE_PT_context_bone)
bpy.types.register(BONE_PT_transform)
bpy.types.register(BONE_PT_transform_locks)
-bpy.types.register(BONE_PT_bone)
+bpy.types.register(BONE_PT_relations)
+bpy.types.register(BONE_PT_display)
bpy.types.register(BONE_PT_deform)
-bpy.types.register(BONE_PT_inverse_kinematics)
-bpy.types.register(BONE_PT_iksolver_itasc)
diff --git a/release/scripts/ui/buttons_data_lamp.py b/release/scripts/ui/buttons_data_lamp.py
index 86ca5beb9b5..2879da8d8d5 100644
--- a/release/scripts/ui/buttons_data_lamp.py
+++ b/release/scripts/ui/buttons_data_lamp.py
@@ -249,7 +249,7 @@ class DATA_PT_area(DataButtonsPanel):
split = layout.split()
col = split.column()
- col.itemR(lamp, "shape", text="")
+ col.row().itemR(lamp, "shape", expand=True)
sub = col.column(align=True)
if (lamp.shape == 'SQUARE'):
@@ -273,9 +273,9 @@ class DATA_PT_spot(DataButtonsPanel):
split = layout.split()
col = split.column()
- sub = col.column(align=True)
+ sub = col.column()
sub.itemR(lamp, "spot_size", text="Size")
- sub.itemR(lamp, "spot_blend", text="Blend")
+ sub.itemR(lamp, "spot_blend", text="Blend", slider=True)
col.itemR(lamp, "square")
col = split.column()
diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py
index 448cb36e130..2415d636dab 100644
--- a/release/scripts/ui/buttons_material.py
+++ b/release/scripts/ui/buttons_material.py
@@ -609,6 +609,23 @@ class VolumeButtonsPanel(bpy.types.Panel):
mat = context.material
engine = context.scene.render_data.engine
return mat and (mat.type == 'VOLUME') and (engine in self.COMPAT_ENGINES)
+
+class MATERIAL_PT_volume_density(VolumeButtonsPanel):
+ __label__ = "Density"
+ __default_closed__ = False
+ COMPAT_ENGINES = set(['BLENDER_RENDER'])
+
+ def draw(self, context):
+ layout = self.layout
+
+ mat = context.material
+ vol = context.material.volume
+
+ split = layout.split()
+ row = split.row()
+ row.itemR(vol, "density")
+ row.itemR(vol, "density_scale")
+
class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
__label__ = "Shading"
@@ -620,22 +637,23 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel):
vol = context.material.volume
- row = layout.row()
- row.itemR(vol, "density")
- row.itemR(vol, "scattering")
-
split = layout.split()
col = split.column()
- col.itemR(vol, "absorption")
- col.itemR(vol, "absorption_color", text="")
-
+ col.itemR(vol, "scattering")
+ col.itemR(vol, "asymmetry")
+ col.itemR(vol, "transmission_color")
+
col = split.column()
- col.itemR(vol, "emission")
- col.itemR(vol, "emission_color", text="")
+ sub = col.column(align=True)
+ sub.itemR(vol, "emission")
+ sub.itemR(vol, "emission_color", text="")
+ sub = col.column(align=True)
+ sub.itemR(vol, "reflection")
+ sub.itemR(vol, "reflection_color", text="")
-class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
- __label__ = "Scattering"
+class MATERIAL_PT_volume_lighting(VolumeButtonsPanel):
+ __label__ = "Lighting"
__default_closed__ = False
COMPAT_ENGINES = set(['BLENDER_RENDER'])
@@ -647,25 +665,28 @@ class MATERIAL_PT_volume_scattering(VolumeButtonsPanel):
split = layout.split()
col = split.column()
- col.itemR(vol, "scattering_mode", text="")
- if vol.scattering_mode == 'SINGLE_SCATTERING':
+ col.itemR(vol, "lighting_mode", text="")
+
+ col = split.column()
+
+ if vol.lighting_mode == 'SHADED':
+ col.itemR(vol, "external_shadows")
col.itemR(vol, "light_cache")
sub = col.column()
sub.active = vol.light_cache
sub.itemR(vol, "cache_resolution")
- elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'):
+ elif vol.lighting_mode in ('MULTIPLE_SCATTERING', 'SHADED_PLUS_MULTIPLE_SCATTERING'):
+ sub = col.column()
+ sub.enabled = True
+ sub.active = False
+ sub.itemR(vol, "light_cache")
col.itemR(vol, "cache_resolution")
sub = col.column(align=True)
sub.itemR(vol, "ms_diffusion")
sub.itemR(vol, "ms_spread")
sub.itemR(vol, "ms_intensity")
-
- col = split.column()
- # col.itemL(text="Anisotropic Scattering:")
- col.itemR(vol, "phase_function", text="")
- if vol.phase_function in ('SCHLICK', 'HENYEY-GREENSTEIN'):
- col.itemR(vol, "asymmetry")
+
class MATERIAL_PT_volume_transp(VolumeButtonsPanel):
__label__= "Transparency"
@@ -693,16 +714,15 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel):
col = split.column()
col.itemL(text="Step Calculation:")
col.itemR(vol, "step_calculation", text="")
- sub = col.column(align=True)
- sub.itemR(vol, "step_size")
- sub.itemR(vol, "shading_step_size")
+ col = col.column(align=True)
+ col.itemR(vol, "step_size")
col = split.column()
col.itemL()
col.itemR(vol, "depth_cutoff")
- col.itemR(vol, "density_scale")
+bpy.types.register(MATERIAL_PT_volume_density)
bpy.types.register(MATERIAL_PT_volume_shading)
-bpy.types.register(MATERIAL_PT_volume_scattering)
+bpy.types.register(MATERIAL_PT_volume_lighting)
bpy.types.register(MATERIAL_PT_volume_transp)
bpy.types.register(MATERIAL_PT_volume_integration)
diff --git a/release/scripts/ui/buttons_object.py b/release/scripts/ui/buttons_object.py
index c069572aa28..d546ddb8fd8 100644
--- a/release/scripts/ui/buttons_object.py
+++ b/release/scripts/ui/buttons_object.py
@@ -26,7 +26,7 @@ class OBJECT_PT_transform(ObjectButtonsPanel):
ob = context.object
- layout.itemR(ob, "rotation_mode")
+
row = layout.row()
@@ -43,6 +43,8 @@ class OBJECT_PT_transform(ObjectButtonsPanel):
row.column().itemR(ob, "scale")
+ layout.itemR(ob, "rotation_mode")
+
class OBJECT_PT_transform_locks(ObjectButtonsPanel):
__label__ = "Transform Locks"
__default_closed__ = True
diff --git a/release/scripts/ui/buttons_object_constraint.py b/release/scripts/ui/buttons_object_constraint.py
index e089cff264f..6be166e8af0 100644
--- a/release/scripts/ui/buttons_object_constraint.py
+++ b/release/scripts/ui/buttons_object_constraint.py
@@ -536,6 +536,145 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel):
for con in ob.constraints:
self.draw_constraint(context, con)
+class BONE_PT_inverse_kinematics(ConstraintButtonsPanel):
+ __label__ = "Inverse Kinematics"
+ __default_closed__ = True
+ __context__ = "bone_constraint"
+
+ def poll(self, context):
+ ob = context.object
+ bone = context.bone
+
+ if ob and bone:
+ pchan = ob.pose.pose_channels[bone.name]
+ return pchan.has_ik
+
+ return False
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ bone = context.bone
+ pchan = ob.pose.pose_channels[bone.name]
+
+ row = layout.row()
+ row.itemR(ob.pose, "ik_solver")
+
+ split = layout.split(percentage=0.25)
+ split.itemR(pchan, "ik_dof_x", text="X")
+ row = split.row()
+ row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
+ row.active = pchan.ik_dof_x
+
+ split = layout.split(percentage=0.25)
+ row = split.row()
+ row.itemR(pchan, "ik_limit_x", text="Limit")
+ row.active = pchan.ik_dof_x
+ row = split.row(align=True)
+ row.itemR(pchan, "ik_min_x", text="")
+ row.itemR(pchan, "ik_max_x", text="")
+ row.active = pchan.ik_dof_x and pchan.ik_limit_x
+
+ split = layout.split(percentage=0.25)
+ split.itemR(pchan, "ik_dof_y", text="Y")
+ row = split.row()
+ row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
+ row.active = pchan.ik_dof_y
+
+ split = layout.split(percentage=0.25)
+ row = split.row()
+ row.itemR(pchan, "ik_limit_y", text="Limit")
+ row.active = pchan.ik_dof_y
+ row = split.row(align=True)
+ row.itemR(pchan, "ik_min_y", text="")
+ row.itemR(pchan, "ik_max_y", text="")
+ row.active = pchan.ik_dof_y and pchan.ik_limit_y
+
+ split = layout.split(percentage=0.25)
+ split.itemR(pchan, "ik_dof_z", text="Z")
+ row = split.row()
+ row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
+ row.active = pchan.ik_dof_z
+
+ split = layout.split(percentage=0.25)
+ row = split.row()
+ row.itemR(pchan, "ik_limit_z", text="Limit")
+ row.active = pchan.ik_dof_z
+ row = split.row(align=True)
+ row.itemR(pchan, "ik_min_z", text="")
+ row.itemR(pchan, "ik_max_z", text="")
+ row.active = pchan.ik_dof_z and pchan.ik_limit_z
+ split = layout.split()
+ split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
+ split.itemL()
+
+ if ob.pose.ik_solver == "ITASC":
+ layout.itemL(text="Joint constraint:")
+ split = layout.split(percentage=0.3)
+ row = split.row()
+ row.itemR(pchan, "ik_rot_control", text="Rotation")
+ row = split.row()
+ row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
+ row.active = pchan.ik_rot_control
+ # not supported yet
+ #split = layout.split(percentage=0.3)
+ #row = split.row()
+ #row.itemR(pchan, "ik_lin_control", text="Size")
+ #row = split.row()
+ #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
+ #row.active = pchan.ik_lin_control
+
+class BONE_PT_iksolver_itasc(ConstraintButtonsPanel):
+ __label__ = "iTaSC parameters"
+ __default_closed__ = True
+ __context__ = "bone_constraint"
+
+ def poll(self, context):
+ ob = context.object
+ bone = context.bone
+
+ if ob and bone:
+ pchan = ob.pose.pose_channels[bone.name]
+ return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
+
+ return False
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ itasc = ob.pose.ik_param
+
+ layout.itemR(itasc, "mode", expand=True)
+ simulation = itasc.mode == "SIMULATION"
+ if simulation:
+ layout.itemL(text="Reiteration:")
+ layout.itemR(itasc, "reiteration", expand=True)
+
+ flow = layout.column_flow()
+ flow.itemR(itasc, "precision", text="Prec")
+ flow.itemR(itasc, "num_iter", text="Iter")
+ flow.active = not simulation or itasc.reiteration != "NEVER"
+
+ if simulation:
+ layout.itemR(itasc, "auto_step")
+ row = layout.row()
+ if itasc.auto_step:
+ row.itemR(itasc, "min_step", text="Min")
+ row.itemR(itasc, "max_step", text="Max")
+ else:
+ row.itemR(itasc, "num_step")
+
+ layout.itemR(itasc, "solver")
+ if simulation:
+ layout.itemR(itasc, "feedback")
+ layout.itemR(itasc, "max_velocity")
+ if itasc.solver == "DLS":
+ row = layout.row()
+ row.itemR(itasc, "dampmax", text="Damp", slider=True)
+ row.itemR(itasc, "dampeps", text="Eps", slider=True)
+
class BONE_PT_constraints(ConstraintButtonsPanel):
__label__ = "Constraints"
__context__ = "bone_constraint"
@@ -558,4 +697,6 @@ class BONE_PT_constraints(ConstraintButtonsPanel):
self.draw_constraint(context, con)
bpy.types.register(OBJECT_PT_constraints)
+bpy.types.register(BONE_PT_iksolver_itasc)
+bpy.types.register(BONE_PT_inverse_kinematics)
bpy.types.register(BONE_PT_constraints)
diff --git a/release/scripts/ui/buttons_particle.py b/release/scripts/ui/buttons_particle.py
index e72bd38e563..81ddab40ec9 100644
--- a/release/scripts/ui/buttons_particle.py
+++ b/release/scripts/ui/buttons_particle.py
@@ -1,6 +1,11 @@
import bpy
+from buttons_physics_common import point_cache_ui
+from buttons_physics_common import effector_weights_ui
+from buttons_physics_common import basic_force_field_settings_ui
+from buttons_physics_common import basic_force_field_falloff_ui
+
def particle_panel_enabled(psys):
return psys.point_cache.baked==False and psys.edited==False
@@ -10,72 +15,6 @@ def particle_panel_poll(context):
if psys.settings==None: return False
return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
-def point_cache_ui(self, cache, enabled, particles, smoke):
- layout = self.layout
- layout.set_context_pointer("PointCache", cache)
-
- row = layout.row()
- row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
- col = row.column(align=True)
- col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
- col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
-
- row = layout.row()
- row.itemL(text="File Name:")
- if particles:
- row.itemR(cache, "external")
-
- if cache.external:
- split = layout.split(percentage=0.80)
- split.itemR(cache, "name", text="")
- split.itemR(cache, "index", text="")
-
- layout.itemL(text="File Path:")
- layout.itemR(cache, "filepath", text="")
-
- layout.itemL(text=cache.info)
- else:
- layout.itemR(cache, "name", text="")
-
- if not particles:
- row = layout.row()
- row.enabled = enabled
- row.itemR(cache, "start_frame")
- row.itemR(cache, "end_frame")
-
- row = layout.row()
-
- if cache.baked == True:
- row.itemO("ptcache.free_bake", text="Free Bake")
- else:
- row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
-
- sub = row.row()
- sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
- sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
-
- row = layout.row()
- row.enabled = enabled
- row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
- if not smoke:
- row.itemR(cache, "step");
-
- if not smoke:
- row = layout.row()
- sub = row.row()
- sub.enabled = enabled
- sub.itemR(cache, "quick_cache")
- row.itemR(cache, "disk_cache")
-
- layout.itemL(text=cache.info)
-
- layout.itemS()
-
- row = layout.row()
- row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
- row.itemO("ptcache.free_bake_all", text="Free All Bakes")
- layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
-
class ParticleButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
@@ -182,17 +121,19 @@ class PARTICLE_PT_emission(ParticleButtonsPanel):
layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches
row = layout.row()
+ row.active = part.distribution != 'GRID'
row.itemR(part, "amount")
- split = layout.split()
-
- col = split.column(align=True)
- col.itemR(part, "start")
- col.itemR(part, "end")
+ if part.type != 'HAIR':
+ split = layout.split()
+
+ col = split.column(align=True)
+ col.itemR(part, "start")
+ col.itemR(part, "end")
- col = split.column(align=True)
- col.itemR(part, "lifetime")
- col.itemR(part, "random_lifetime", slider=True)
+ col = split.column(align=True)
+ col.itemR(part, "lifetime")
+ col.itemR(part, "random_lifetime", slider=True)
layout.row().itemL(text="Emit From:")
@@ -245,23 +186,22 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
split = layout.split()
col = split.column()
- col.itemL(text="Quality:")
- col.itemR(cloth, "quality", text="Steps",slider=True)
- col.itemL(text="Gravity:")
- col.itemR(cloth, "gravity", text="")
-
- col = split.column()
col.itemL(text="Material:")
sub = col.column(align=True)
sub.itemR(cloth, "pin_stiffness", text="Stiffness")
sub.itemR(cloth, "mass")
sub.itemR(cloth, "bending_stiffness", text="Bending")
+ sub.itemR(cloth, "internal_friction", slider="True")
+
+ col = split.column()
+
col.itemL(text="Damping:")
sub = col.column(align=True)
sub.itemR(cloth, "spring_damping", text="Spring")
sub.itemR(cloth, "air_damping", text="Air")
- layout.itemR(cloth, "internal_friction", slider="True")
+ col.itemL(text="Quality:")
+ col.itemR(cloth, "quality", text="Steps",slider=True)
class PARTICLE_PT_cache(ParticleButtonsPanel):
__label__ = "Cache"
@@ -283,7 +223,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel):
point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0)
-class PARTICLE_PT_initial(ParticleButtonsPanel):
+class PARTICLE_PT_velocity(ParticleButtonsPanel):
__label__ = "Velocity"
def poll(self, context):
@@ -300,48 +240,66 @@ class PARTICLE_PT_initial(ParticleButtonsPanel):
part = psys.settings
layout.enabled = particle_panel_enabled(psys)
-
- layout.row().itemL(text="Direction:")
split = layout.split()
sub = split.column()
+ sub.itemL(text="Emitter Geometry:")
sub.itemR(part, "normal_factor")
+ subsub = sub.column(align=True)
+ subsub.itemR(part, "tangent_factor")
+ subsub.itemR(part, "tangent_phase", slider=True)
+
+ sub = split.column()
+ sub.itemL(text="Emitter Object")
+ sub.itemR(part, "object_aligned_factor", text="")
+
+ layout.row().itemL(text="Other:")
+ split = layout.split()
+ sub = split.column()
if part.emit_from=='PARTICLE':
sub.itemR(part, "particle_factor")
else:
sub.itemR(part, "object_factor", slider=True)
+ sub = split.column()
sub.itemR(part, "random_factor")
- sub.itemR(part, "tangent_factor")
- sub.itemR(part, "tangent_phase", slider=True)
- sub = split.column()
- sub.itemL(text="TODO:")
- sub.itemL(text="Object aligned")
- sub.itemL(text="direction: X, Y, Z")
+ #if part.type=='REACTOR':
+ # sub.itemR(part, "reactor_factor")
+ # sub.itemR(part, "reaction_shape", slider=True)
- if part.type=='REACTOR':
- sub.itemR(part, "reactor_factor")
- sub.itemR(part, "reaction_shape", slider=True)
+class PARTICLE_PT_rotation(ParticleButtonsPanel):
+ __label__ = "Rotation"
+
+ def poll(self, context):
+ if particle_panel_poll(context):
+ psys = context.particle_system
+ return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
else:
- sub.itemL(text="")
+ return False
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ part = psys.settings
- layout.row().itemL(text="Rotation:")
- split = layout.split()
-
- sub = split.column()
+ layout.enabled = particle_panel_enabled(psys)
- sub.itemR(part, "rotation_mode", text="Axis")
+ split = layout.split()
+ split.itemL(text="Initial Rotation:")
+ split.itemR(part, "rotation_dynamic")
split = layout.split()
- sub = split.column()
- sub.itemR(part, "rotation_dynamic")
- sub.itemR(part, "random_rotation_factor", slider=True)
- sub = split.column()
+ sub = split.column(align=True)
+ sub.itemR(part, "rotation_mode", text="")
+ sub.itemR(part, "random_rotation_factor", slider=True, text="Random")
+
+ sub = split.column(align=True)
sub.itemR(part, "phase_factor", slider=True)
sub.itemR(part, "random_phase_factor", text="Random", slider=True)
- layout.row().itemL(text="Angular velocity:")
+ layout.row().itemL(text="Angular Velocity:")
layout.row().itemR(part, "angular_velocity_mode", expand=True)
split = layout.split()
@@ -385,9 +343,11 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
sub.itemR(part, "brownian_factor")
sub.itemR(part, "drag_factor", slider=True)
sub.itemR(part, "damp_factor", slider=True)
- sub.itemR(part, "integrator")
sub = split.column()
- sub.itemR(part, "acceleration")
+ sub.itemR(part, "size_deflect")
+ sub.itemR(part, "die_on_collision")
+ sub.itemR(part, "integrator")
+ sub.itemR(part, "time_tweak")
elif part.physics_type == 'KEYED':
split = layout.split()
@@ -445,14 +405,10 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
col = row.column()
col.itemL(text="Misc:")
- col.itemR(part, "gravity")
col.itemR(boids, "banking", slider=True)
col.itemR(boids, "height", slider=True)
- if part.physics_type=='NEWTON':
- sub.itemR(part, "size_deflect")
- sub.itemR(part, "die_on_collision")
- elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
+ if part.physics_type=='KEYED' or part.physics_type=='BOIDS':
if part.physics_type=='BOIDS':
layout.itemL(text="Relations:")
@@ -505,18 +461,18 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
boids = context.particle_system.settings.boids
layout = self.layout
- layout.enabled = particle_panel_enabled(psys)
+ layout.enabled = particle_panel_enabled(context.particle_system)
# Currently boids can only use the first state so these are commented out for now.
#row = layout.row()
#row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
#col = row.row()
#subrow = col.row(align=True)
- #subrow.itemO("boid.boidstate_add", icon='ICON_ZOOMIN', text="")
- #subrow.itemO("boid.boidstate_del", icon='ICON_ZOOMOUT', text="")
+ #subrow.itemO("boid.state_add", icon='ICON_ZOOMIN', text="")
+ #subrow.itemO("boid.state_del", icon='ICON_ZOOMOUT', text="")
#subrow = row.row(align=True)
- #subrow.itemO("boid.boidstate_move_up", icon='VICON_MOVE_UP', text="")
- #subrow.itemO("boid.boidstate_move_down", icon='VICON_MOVE_DOWN', text="")
+ #subrow.itemO("boid.state_move_up", icon='VICON_MOVE_UP', text="")
+ #subrow.itemO("boid.state_move_down", icon='VICON_MOVE_DOWN', text="")
state = boids.active_boid_state
@@ -535,12 +491,12 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
col = row.column()
subrow = col.row()
subcol = subrow.column(align=True)
- subcol.item_menu_enumO("boid.boidrule_add", "type", icon='ICON_ZOOMIN', text="")
- subcol.itemO("boid.boidrule_del", icon='ICON_ZOOMOUT', text="")
+ subcol.item_menu_enumO("boid.rule_add", "type", icon='ICON_ZOOMIN', text="")
+ subcol.itemO("boid.rule_del", icon='ICON_ZOOMOUT', text="")
subrow = col.row()
subcol = subrow.column(align=True)
- subcol.itemO("boid.boidrule_move_up", icon='VICON_MOVE_UP', text="")
- subcol.itemO("boid.boidrule_move_down", icon='VICON_MOVE_DOWN', text="")
+ subcol.itemO("boid.rule_move_up", icon='VICON_MOVE_UP', text="")
+ subcol.itemO("boid.rule_move_down", icon='VICON_MOVE_DOWN', text="")
rule = state.active_boid_rule
@@ -671,16 +627,37 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
elif part.ren_as == 'OBJECT':
sub.itemR(part, "dupli_object")
+ sub.itemR(part, "use_global_dupli")
elif part.ren_as == 'GROUP':
sub.itemR(part, "dupli_group")
split = layout.split()
sub = split.column()
sub.itemR(part, "whole_group")
+ colsub = sub.column()
+ colsub.active = part.whole_group == False
+ colsub.itemR(part, "use_group_count")
+
sub = split.column()
colsub = sub.column()
colsub.active = part.whole_group == False
+ colsub.itemR(part, "use_global_dupli")
colsub.itemR(part, "rand_group")
+ if part.use_group_count and not part.whole_group:
+ row = layout.row()
+ row.template_list(part, "dupliweights", part, "active_dupliweight_index")
+
+ col = row.column()
+ subrow = col.row()
+ subcol = subrow.column(align=True)
+ subcol.itemO("particle.dupliob_move_up", icon='VICON_MOVE_UP', text="")
+ subcol.itemO("particle.dupliob_move_down", icon='VICON_MOVE_DOWN', text="")
+
+ weight = part.active_dupliweight
+ if weight:
+ row = layout.row()
+ row.itemR(weight, "count")
+
elif part.ren_as == 'BILLBOARD':
sub.itemL(text="Align:")
@@ -857,30 +834,41 @@ class PARTICLE_PT_children(ParticleButtonsPanel):
sub = split.column()
sub.itemR(part, "kink_shape", slider=True)
-class PARTICLE_PT_effectors(ParticleButtonsPanel):
- __label__ = "Effectors"
+class PARTICLE_PT_field_weights(ParticleButtonsPanel):
+ __label__ = "Field Weights"
+ __default_closed__ = True
+
+ def draw(self, context):
+ part = context.particle_system.settings
+ effector_weights_ui(self, part.effector_weights)
+
+ if part.type == 'HAIR':
+ self.layout.itemR(part.effector_weights, "do_growing_hair")
+
+class PARTICLE_PT_force_fields(ParticleButtonsPanel):
+ __label__ = "Force Field Settings"
__default_closed__ = True
def draw(self, context):
layout = self.layout
-
- psys = context.particle_system
- part = psys.settings
+ part = context.particle_system.settings
- layout.itemR(part, "effector_group")
+ layout.itemR(part, "self_effect")
- layout.itemR(part, "eweight_all", slider=True)
+ split = layout.split(percentage=0.2)
+ split.itemL(text="Type 1:")
+ split.itemR(part.force_field_1, "type",text="")
+ basic_force_field_settings_ui(self, part.force_field_1)
+ basic_force_field_falloff_ui(self, part.force_field_1)
- layout.itemS()
- layout.itemR(part, "eweight_spherical", slider=True)
- layout.itemR(part, "eweight_vortex", slider=True)
- layout.itemR(part, "eweight_magnetic", slider=True)
- layout.itemR(part, "eweight_wind", slider=True)
- layout.itemR(part, "eweight_curveguide", slider=True)
- layout.itemR(part, "eweight_texture", slider=True)
- layout.itemR(part, "eweight_harmonic", slider=True)
- layout.itemR(part, "eweight_charge", slider=True)
- layout.itemR(part, "eweight_lennardjones", slider=True)
+ if part.force_field_1.type != 'NONE':
+ layout.itemL(text="")
+
+ split = layout.split(percentage=0.2)
+ split.itemL(text="Type 2:")
+ split.itemR(part.force_field_2, "type",text="")
+ basic_force_field_settings_ui(self, part.force_field_2)
+ basic_force_field_falloff_ui(self, part.force_field_2)
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
__label__ = "Vertexgroups"
@@ -951,11 +939,13 @@ bpy.types.register(PARTICLE_PT_particles)
bpy.types.register(PARTICLE_PT_hair_dynamics)
bpy.types.register(PARTICLE_PT_cache)
bpy.types.register(PARTICLE_PT_emission)
-bpy.types.register(PARTICLE_PT_initial)
+bpy.types.register(PARTICLE_PT_velocity)
+bpy.types.register(PARTICLE_PT_rotation)
bpy.types.register(PARTICLE_PT_physics)
bpy.types.register(PARTICLE_PT_boidbrain)
bpy.types.register(PARTICLE_PT_render)
bpy.types.register(PARTICLE_PT_draw)
bpy.types.register(PARTICLE_PT_children)
-bpy.types.register(PARTICLE_PT_effectors)
+bpy.types.register(PARTICLE_PT_field_weights)
+bpy.types.register(PARTICLE_PT_force_fields)
bpy.types.register(PARTICLE_PT_vertexgroups)
diff --git a/release/scripts/ui/buttons_physics_cloth.py b/release/scripts/ui/buttons_physics_cloth.py
index f6493951a34..e25497b3713 100644
--- a/release/scripts/ui/buttons_physics_cloth.py
+++ b/release/scripts/ui/buttons_physics_cloth.py
@@ -1,7 +1,8 @@
import bpy
-from buttons_particle import point_cache_ui
+from buttons_physics_common import point_cache_ui
+from buttons_physics_common import effector_weights_ui
def cloth_panel_enabled(md):
return md.point_cache.baked==False
@@ -49,10 +50,11 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
split = layout.split()
col = split.column()
- col.itemL(text="Quality:")
- col.itemR(cloth, "quality", text="Steps",slider=True)
- col.itemL(text="Gravity:")
- col.itemR(cloth, "gravity", text="")
+ col.itemL(text="Material:")
+ sub = col.column(align=True)
+ sub.itemR(cloth, "mass")
+ sub.itemR(cloth, "structural_stiffness", text="Structural")
+ sub.itemR(cloth, "bending_stiffness", text="Bending")
col.itemR(cloth, "pin_cloth", text="Pin")
sub = col.column(align=True)
@@ -61,18 +63,18 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
sub.item_pointerR(cloth, "mass_vertex_group", ob, "vertex_groups", text="")
col = split.column()
- col.itemL(text="Presets...")
- col.itemL(text="TODO!")
- col.itemL(text="Material:")
- sub = col.column(align=True)
- sub.itemR(cloth, "mass")
- sub.itemR(cloth, "structural_stiffness", text="Structural")
- sub.itemR(cloth, "bending_stiffness", text="Bending")
+
col.itemL(text="Damping:")
sub = col.column(align=True)
sub.itemR(cloth, "spring_damping", text="Spring")
sub.itemR(cloth, "air_damping", text="Air")
+ col.itemL(text="Presets...")
+ col.itemL(text="TODO!")
+
+ col.itemL(text="Quality:")
+ col.itemR(cloth, "quality", text="Steps",slider=True)
+
# Disabled for now
"""
if cloth.mass_vertex_group:
@@ -165,8 +167,20 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
sub = col.column(align=True)
sub.itemR(cloth, "bending_stiffness_max", text="Max")
sub.item_pointerR(cloth, "bending_vertex_group", ob, "vertex_groups", text="")
+
+class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel):
+ __label__ = "Cloth Field Weights"
+ __default_closed__ = True
+
+ def poll(self, context):
+ return (context.cloth)
+
+ def draw(self, context):
+ cloth = context.cloth.settings
+ effector_weights_ui(self, cloth.effector_weights)
bpy.types.register(PHYSICS_PT_cloth)
bpy.types.register(PHYSICS_PT_cloth_cache)
bpy.types.register(PHYSICS_PT_cloth_collision)
bpy.types.register(PHYSICS_PT_cloth_stiffness)
+bpy.types.register(PHYSICS_PT_cloth_field_weights)
diff --git a/release/scripts/ui/buttons_physics_common.py b/release/scripts/ui/buttons_physics_common.py
new file mode 100644
index 00000000000..17ac1b2bbaa
--- /dev/null
+++ b/release/scripts/ui/buttons_physics_common.py
@@ -0,0 +1,154 @@
+import bpy
+
+def point_cache_ui(self, cache, enabled, particles, smoke):
+ layout = self.layout
+ layout.set_context_pointer("PointCache", cache)
+
+ row = layout.row()
+ row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2 )
+ col = row.column(align=True)
+ col.itemO("ptcache.add_new", icon='ICON_ZOOMIN', text="")
+ col.itemO("ptcache.remove", icon='ICON_ZOOMOUT', text="")
+
+ row = layout.row()
+ row.itemL(text="File Name:")
+ if particles:
+ row.itemR(cache, "external")
+
+ if cache.external:
+ split = layout.split(percentage=0.80)
+ split.itemR(cache, "name", text="")
+ split.itemR(cache, "index", text="")
+
+ layout.itemL(text="File Path:")
+ layout.itemR(cache, "filepath", text="")
+
+ layout.itemL(text=cache.info)
+ else:
+ layout.itemR(cache, "name", text="")
+
+ if not particles:
+ row = layout.row()
+ row.enabled = enabled
+ row.itemR(cache, "start_frame")
+ row.itemR(cache, "end_frame")
+
+ row = layout.row()
+
+ if cache.baked == True:
+ row.itemO("ptcache.free_bake", text="Free Bake")
+ else:
+ row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
+
+ sub = row.row()
+ sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
+ sub.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
+
+ row = layout.row()
+ row.enabled = enabled
+ row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
+ if not smoke:
+ row.itemR(cache, "step");
+
+ if not smoke:
+ row = layout.row()
+ sub = row.row()
+ sub.enabled = enabled
+ sub.itemR(cache, "quick_cache")
+ row.itemR(cache, "disk_cache")
+
+ layout.itemL(text=cache.info)
+
+ layout.itemS()
+
+ row = layout.row()
+ row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
+ row.itemO("ptcache.free_bake_all", text="Free All Bakes")
+ layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
+
+def effector_weights_ui(self, weights):
+ layout = self.layout
+
+ layout.itemR(weights, "group")
+
+ split = layout.split()
+ split.itemR(weights, "gravity", slider=True)
+ split.itemR(weights, "all", slider=True)
+
+ layout.itemS()
+
+ flow = layout.column_flow()
+ flow.itemR(weights, "force", slider=True)
+ flow.itemR(weights, "vortex", slider=True)
+ flow.itemR(weights, "magnetic", slider=True)
+ flow.itemR(weights, "wind", slider=True)
+ flow.itemR(weights, "curveguide", slider=True)
+ flow.itemR(weights, "texture", slider=True)
+ flow.itemR(weights, "harmonic", slider=True)
+ flow.itemR(weights, "charge", slider=True)
+ flow.itemR(weights, "lennardjones", slider=True)
+ flow.itemR(weights, "turbulence", slider=True)
+ flow.itemR(weights, "drag", slider=True)
+ flow.itemR(weights, "boid", slider=True)
+
+def basic_force_field_settings_ui(self, field):
+ layout = self.layout
+ split = layout.split()
+
+ if not field or field.type == 'NONE':
+ return
+
+ col = split.column()
+
+ if field.type == 'DRAG':
+ col.itemR(field, "linear_drag", text="Linear")
+ else:
+ col.itemR(field, "strength")
+
+ if field.type == 'TURBULENCE':
+ col.itemR(field, "size")
+ col.itemR(field, "flow")
+ elif field.type == 'HARMONIC':
+ col.itemR(field, "harmonic_damping", text="Damping")
+ elif field.type == 'VORTEX' and field.shape != 'POINT':
+ col.itemR(field, "inflow")
+ elif field.type == 'DRAG':
+ col.itemR(field, "quadratic_drag", text="Quadratic")
+ else:
+ col.itemR(field, "flow")
+
+ col = split.column()
+ col.itemR(field, "noise")
+ col.itemR(field, "seed")
+ if field.type == 'TURBULENCE':
+ col.itemR(field, "global_coordinates", text="Global")
+
+ row = layout.row()
+ row.itemL(text="Effect point:")
+ row.itemR(field, "do_location")
+ row.itemR(field, "do_rotation")
+
+
+def basic_force_field_falloff_ui(self, field):
+ layout = self.layout
+ split = layout.split(percentage=0.35)
+
+ if not field or field.type == 'NONE':
+ return
+
+ col = split.column()
+ col.itemR(field, "z_direction", text="")
+ col.itemR(field, "use_min_distance", text="Use Minimum")
+ col.itemR(field, "use_max_distance", text="Use Maximum")
+ col.itemR(field, "do_absorption")
+
+ col = split.column()
+ col.itemR(field, "falloff_power", text="Power")
+
+ sub = col.column()
+ sub.active = field.use_min_distance
+ sub.itemR(field, "minimum_distance", text="Distance")
+
+ sub = col.column()
+ sub.active = field.use_max_distance
+ sub.itemR(field, "maximum_distance", text="Distance") \ No newline at end of file
diff --git a/release/scripts/ui/buttons_physics_field.py b/release/scripts/ui/buttons_physics_field.py
index 7d14690856a..9aec0404ab1 100644
--- a/release/scripts/ui/buttons_physics_field.py
+++ b/release/scripts/ui/buttons_physics_field.py
@@ -1,6 +1,9 @@
import bpy
+from buttons_physics_common import basic_force_field_settings_ui
+from buttons_physics_common import basic_force_field_falloff_ui
+
class PhysicButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
__region_type__ = 'WINDOW'
@@ -12,61 +15,55 @@ class PhysicButtonsPanel(bpy.types.Panel):
class PHYSICS_PT_field(PhysicButtonsPanel):
__label__ = "Force Fields"
- __default_closed__ = True
def draw(self, context):
layout = self.layout
ob = context.object
field = ob.field
-
- #layout.active = field.enabled
split = layout.split(percentage=0.2)
-
split.itemL(text="Type:")
split.itemR(field, "type",text="")
+
+ if field.type not in ('NONE', 'GUIDE', 'TEXTURE'):
+ split = layout.split(percentage=0.2)
+ #split = layout.row()
+ split.itemL(text="Shape:")
+ split.itemR(field, "shape", text="")
split = layout.split()
- if field.type == 'GUIDE':
- layout.itemR(field, "guide_path_add")
-
- elif field.type == 'WIND':
- split.itemR(field, "strength")
-
+ if field.type == 'NONE':
+ return # nothing to draw
+ elif field.type == 'GUIDE':
col = split.column()
- col.itemR(field, "noise")
- col.itemR(field, "seed")
-
- elif field.type == 'VORTEX':
- split.itemR(field, "strength")
- split.itemL()
-
- elif field.type in ('SPHERICAL', 'CHARGE', 'LENNARDJ'):
- split.itemR(field, "strength")
+ col.itemR(field, "guide_minimum")
+ col.itemR(field, "guide_free")
+ col.itemR(field, "falloff_power")
+ col.itemR(field, "guide_path_add")
col = split.column()
- col.itemR(field, "planar")
- col.itemR(field, "surface")
-
- elif field.type == 'BOID':
- split.itemR(field, "strength")
- split.itemR(field, "surface")
+ col.itemL(text="Clumping:")
+ col.itemR(field, "guide_clump_amount")
+ col.itemR(field, "guide_clump_shape")
- elif field.type == 'MAGNET':
- split.itemR(field, "strength")
- split.itemR(field, "planar")
-
- elif field.type == 'HARMONIC':
- col = split.column()
- col.itemR(field, "strength")
- col.itemR(field, "harmonic_damping", text="Damping")
-
- col = split.column()
- col.itemR(field, "planar")
- col.itemR(field, "surface")
+ row = layout.row()
+ row.itemR(field, "use_max_distance")
+ sub = row.row()
+ sub.active = field.use_max_distance
+ sub.itemR(field, "maximum_distance")
+ layout.itemS()
+
+ layout.itemR(field, "guide_kink_type")
+ if (field.guide_kink_type != "NONE"):
+ layout.itemR(field, "guide_kink_axis")
+
+ flow = layout.column_flow()
+ flow.itemR(field, "guide_kink_frequency")
+ flow.itemR(field, "guide_kink_shape")
+ flow.itemR(field, "guide_kink_amplitude")
elif field.type == 'TEXTURE':
col = split.column()
col.itemR(field, "strength")
@@ -78,29 +75,15 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
col.itemR(field, "use_coordinates")
col.itemR(field, "root_coordinates")
col.itemR(field, "force_2d")
+ else :
+ basic_force_field_settings_ui(self, field)
- if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', 'WIND', 'VORTEX', 'TEXTURE', 'MAGNET', 'BOID'):
+ if field.type not in ('NONE', 'GUIDE'):
layout.itemL(text="Falloff:")
layout.itemR(field, "falloff_type", expand=True)
- split = layout.split(percentage=0.35)
-
- col = split.column()
- col.itemR(field, "positive_z", text="Positive Z")
- col.itemR(field, "use_min_distance", text="Use Minimum")
- col.itemR(field, "use_max_distance", text="Use Maximum")
-
- col = split.column()
- col.itemR(field, "falloff_power", text="Power")
-
- sub = col.column()
- sub.active = field.use_min_distance
- sub.itemR(field, "minimum_distance", text="Distance")
-
- sub = col.column()
- sub.active = field.use_max_distance
- sub.itemR(field, "maximum_distance", text="Distance")
+ basic_force_field_falloff_ui(self, field)
if field.falloff_type == 'CONE':
layout.itemS()
@@ -143,21 +126,10 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
sub = col.column()
sub.active = field.use_radial_max
sub.itemR(field, "radial_maximum", text="Distance")
-
- #if ob.type in 'CURVE':
- #if field.type == 'GUIDE':
- #colsub = col.column(align=True)
-
- #if field.type != 'NONE':
- #layout.itemR(field, "strength")
-
- #if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', "LENNARDj"):
- #if ob.type in ('MESH', 'SURFACE', 'FONT', 'CURVE'):
- #layout.itemR(field, "surface")
class PHYSICS_PT_collision(PhysicButtonsPanel):
__label__ = "Collision"
- __default_closed__ = True
+ #__default_closed__ = True
def poll(self, context):
ob = context.object
@@ -182,16 +154,18 @@ class PHYSICS_PT_collision(PhysicButtonsPanel):
#row.itemR(md, "render", text="")
#row.itemR(md, "realtime", text="")
- settings = md.settings
+ coll = md.settings
else:
# add modifier
split.item_enumO("object.modifier_add", "type", 'COLLISION', text="Add")
split.itemL()
- settings = None
+ coll = None
- if settings:
+ if coll:
+ settings = context.object.collision
+
layout.active = settings.enabled
split = layout.split()
diff --git a/release/scripts/ui/buttons_physics_softbody.py b/release/scripts/ui/buttons_physics_softbody.py
index 3bdbb1b8b90..cd66df00044 100644
--- a/release/scripts/ui/buttons_physics_softbody.py
+++ b/release/scripts/ui/buttons_physics_softbody.py
@@ -1,7 +1,8 @@
import bpy
-from buttons_particle import point_cache_ui
+from buttons_physics_common import point_cache_ui
+from buttons_physics_common import effector_weights_ui
def softbody_panel_enabled(md):
return md.point_cache.baked==False
@@ -55,7 +56,6 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel):
col = split.column()
col.itemL(text="Simulation:")
- col.itemR(softbody, "gravity")
col.itemR(softbody, "speed")
class PHYSICS_PT_softbody_cache(PhysicButtonsPanel):
@@ -222,6 +222,18 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
layout.itemL(text="Diagnostics:")
layout.itemR(softbody, "diagnose")
+
+class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel):
+ __label__ = "Soft Body Field Weights"
+ __default_closed__ = True
+
+ def poll(self, context):
+ return (context.soft_body)
+
+ def draw(self, context):
+ md = context.soft_body
+ softbody = md.settings
+ effector_weights_ui(self, softbody.effector_weights)
bpy.types.register(PHYSICS_PT_softbody)
bpy.types.register(PHYSICS_PT_softbody_cache)
@@ -229,3 +241,4 @@ bpy.types.register(PHYSICS_PT_softbody_goal)
bpy.types.register(PHYSICS_PT_softbody_edge)
bpy.types.register(PHYSICS_PT_softbody_collision)
bpy.types.register(PHYSICS_PT_softbody_solver)
+bpy.types.register(PHYSICS_PT_softbody_field_weights)
diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py
index 69cf79ddc85..666bbacea50 100644
--- a/release/scripts/ui/buttons_scene.py
+++ b/release/scripts/ui/buttons_scene.py
@@ -1,6 +1,14 @@
import bpy
+class SceneButtonsPanel(bpy.types.Panel):
+ __space_type__ = 'PROPERTIES'
+ __region_type__ = 'WINDOW'
+ __context__ = "scene"
+
+ def poll(self, context):
+ return (context.scene != None)
+
class RenderButtonsPanel(bpy.types.Panel):
__space_type__ = 'PROPERTIES'
__region_type__ = 'WINDOW'
@@ -455,7 +463,102 @@ class SCENE_PT_unit(RenderButtonsPanel):
row.active = (unit.system != 'NONE')
row.itemR(unit, "scale_length", text="Scale")
row.itemR(unit, "use_separate")
+
+class SCENE_PT_keying_sets(SceneButtonsPanel):
+ __label__ = "Keying Sets"
+ __default_closed__ = True
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+
+ row = layout.row()
+
+ col = row.column()
+ col.template_list(scene, "keying_sets", scene, "active_keying_set_index", rows=2)
+
+ col = row.column(align=True)
+ col.itemO("anim.keying_set_add", icon='ICON_ZOOMIN', text="")
+ col.itemO("anim.keying_set_remove", icon='ICON_ZOOMOUT', text="")
+
+ ks = scene.active_keying_set
+ if ks:
+ row = layout.row()
+
+ col = row.column()
+ col.itemR(ks, "name")
+ col.itemR(ks, "absolute")
+
+ col = row.column()
+ col.itemL(text="Keyframing Settings:")
+ col.itemR(ks, "insertkey_needed", text="Needed")
+ col.itemR(ks, "insertkey_visual", text="Visual")
+
+class SCENE_PT_keying_set_paths(SceneButtonsPanel):
+ __label__ = "Active Keying Set"
+ __default_closed__ = True
+
+ def poll(self, context):
+ return (context.scene != None) and (context.scene.active_keying_set != None)
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ ks = scene.active_keying_set
+
+ row = layout.row()
+
+ col = row.column()
+ col.template_list(ks, "paths", ks, "active_path_index", rows=2)
+
+ col = row.column(align=True)
+ col.itemO("anim.keying_set_path_add", icon='ICON_ZOOMIN', text="")
+ col.itemO("anim.keying_set_path_remove", icon='ICON_ZOOMOUT', text="")
+
+ ksp = ks.active_path
+ if ksp:
+ col = layout.column()
+ col.itemL(text="Target:")
+ col.itemR(ksp, "id")
+ col.itemR(ksp, "rna_path")
+
+
+ row = layout.row()
+
+ col = row.column()
+ col.itemL(text="Array Target:")
+ col.itemR(ksp, "entire_array")
+ if ksp.entire_array == False:
+ col.itemR(ksp, "array_index")
+
+ col = row.column()
+ col.itemL(text="F-Curve Grouping:")
+ col.itemR(ksp, "grouping")
+ if ksp.grouping == 'NAMED':
+ col.itemR(ksp, "group")
+
+
+
+
+class SCENE_PT_physics(RenderButtonsPanel):
+ __label__ = "Gravity"
+ COMPAT_ENGINES = set(['BLENDER_RENDER'])
+ def draw_header(self, context):
+ self.layout.itemR(context.scene, "use_gravity", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+
+ layout.active = scene.use_gravity
+
+ layout.itemR(scene, "gravity", text="")
+
+
bpy.types.register(SCENE_PT_render)
bpy.types.register(SCENE_PT_layers)
bpy.types.register(SCENE_PT_dimensions)
@@ -467,3 +570,6 @@ bpy.types.register(SCENE_PT_performance)
bpy.types.register(SCENE_PT_post_processing)
bpy.types.register(SCENE_PT_stamp)
bpy.types.register(SCENE_PT_unit)
+bpy.types.register(SCENE_PT_keying_sets)
+bpy.types.register(SCENE_PT_keying_set_paths)
+bpy.types.register(SCENE_PT_physics)
diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py
index c95fa266aaa..c4866edcaaa 100644
--- a/release/scripts/ui/buttons_texture.py
+++ b/release/scripts/ui/buttons_texture.py
@@ -99,8 +99,13 @@ class TEXTURE_PT_colors(TextureButtonsPanel):
layout.template_color_ramp(tex, "color_ramp", expand=True)
split = layout.split()
-
- split.itemR(tex, "rgb_factor", text="Multiply RGB")
+
+ col = split.column()
+ col.itemL(text="RGB Multiply:")
+ sub = col.column(align=True)
+ sub.itemR(tex, "factor_red", text="R")
+ sub.itemR(tex, "factor_green", text="G")
+ sub.itemR(tex, "factor_blue", text="B")
col = split.column()
col.itemL(text="Adjust:")
@@ -175,14 +180,14 @@ class TEXTURE_PT_mapping(TextureSlotPanel):
row.itemR(tex, "z_mapping", text="")
if br:
- layout.itemR(tex, "brush_map_mode", expand=True)
+ layout.itemR(tex, "map_mode", expand=True)
row = layout.row()
- row.active = tex.brush_map_mode in ('FIXED', 'TILED')
+ row.active = tex.map_mode in ('FIXED', 'TILED')
row.itemR(tex, "angle")
row = layout.row()
- row.active = tex.brush_map_mode in ('TILED', '3D')
+ row.active = tex.map_mode in ('TILED', '3D')
row.column().itemR(tex, "size")
else:
row = layout.row()
@@ -246,13 +251,14 @@ class TEXTURE_PT_influence(TextureSlotPanel):
col = split.column()
factor_but(col, tex.map_density, "map_density", "density_factor", "Density")
factor_but(col, tex.map_emission, "map_emission", "emission_factor", "Emission")
- factor_but(col, tex.map_absorption, "map_absorption", "absorption_factor", "Absorption")
factor_but(col, tex.map_scattering, "map_scattering", "scattering_factor", "Scattering")
+ factor_but(col, tex.map_reflection, "map_reflection", "reflection_factor", "Reflection")
col = split.column()
col.itemL(text=" ")
factor_but(col, tex.map_alpha, "map_coloremission", "coloremission_factor", "Emission Color")
- factor_but(col, tex.map_colorabsorption, "map_colorabsorption", "colorabsorption_factor", "Absorption Color")
+ factor_but(col, tex.map_colortransmission, "map_colortransmission", "colortransmission_factor", "Transmission Color")
+ factor_but(col, tex.map_colorreflection, "map_colorreflection", "colorreflection_factor", "Reflection Color")
elif la:
row = layout.row()
@@ -642,6 +648,7 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel):
row.itemR(vd, "still_frame_number")
layout.itemR(vd, "interpolation")
+ layout.itemR(vd, "extension")
layout.itemR(vd, "intensity")
class TEXTURE_PT_pointdensity(TextureButtonsPanel):
diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py
index c1a2b1f4275..49261981ac2 100644
--- a/release/scripts/ui/space_info.py
+++ b/release/scripts/ui/space_info.py
@@ -144,6 +144,10 @@ class INFO_MT_add(bpy.types.Menu):
layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP')
+
+ layout.itemS()
+
+ layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY')
class INFO_MT_game(bpy.types.Menu):
__space_type__ = 'INFO'
diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py
index 9798e0ccab6..a9126d2c7f1 100644
--- a/release/scripts/ui/space_userpref.py
+++ b/release/scripts/ui/space_userpref.py
@@ -314,6 +314,7 @@ class USERPREF_PT_system(bpy.types.Panel):
sub1.itemL(text="OpenGL:")
sub1.itemR(system, "clip_alpha", slider=True)
sub1.itemR(system, "use_mipmaps")
+ sub1.itemR(system, "use_vbos")
sub1.itemL(text="Window Draw Method:")
sub1.row().itemR(system, "window_draw_method", expand=True)
sub1.itemL(text="Textures:")
diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py
index 23f3b8a10ac..a270e053126 100644
--- a/release/scripts/ui/space_view3d.py
+++ b/release/scripts/ui/space_view3d.py
@@ -1285,6 +1285,26 @@ class VIEW3D_PT_background_image(bpy.types.Panel):
col.itemR(bg, "offset_x", text="X")
col.itemR(bg, "offset_y", text="Y")
+class VIEW3D_PT_transform_orientations(bpy.types.Panel):
+ __space_type__ = 'VIEW_3D'
+ __region_type__ = 'UI'
+ __label__ = "Transform Orientations"
+ __default_closed__ = True
+
+ def poll(self, context):
+ view = context.space_data
+ return (view)
+
+ def draw(self, context):
+ layout = self.layout
+
+ view = context.space_data
+
+ col = layout.column()
+ col.itemO("TFM_OT_select_orientation", text="Select")
+ col.itemO("TFM_OT_create_orientation", text="Create")
+ col.itemO("TFM_OT_delete_orientation", text="Delete")
+
bpy.types.register(VIEW3D_HT_header) # Header
bpy.types.register(VIEW3D_MT_view) #View Menus
@@ -1360,3 +1380,4 @@ bpy.types.register(VIEW3D_PT_3dview_display)
bpy.types.register(VIEW3D_PT_3dview_meshdisplay)
bpy.types.register(VIEW3D_PT_3dview_curvedisplay)
bpy.types.register(VIEW3D_PT_background_image)
+bpy.types.register(VIEW3D_PT_transform_orientations) \ No newline at end of file