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')
-rwxr-xr-xrelease/bin/blender-thumbnailer.py11
-rw-r--r--release/datafiles/blender_icons.svg347
-rw-r--r--release/datafiles/blender_icons16/icon16_library_data_broken.datbin1048 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_mesh_capsule.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_snap_grid.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_snap_increment.datbin1048 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_library_data_broken.datbin4120 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_mesh_capsule.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_snap_grid.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_snap_increment.datbin4120 -> 4120 bytes
m---------release/datafiles/locale0
-rw-r--r--release/datafiles/splash.pngbin187546 -> 140110 bytes
-rw-r--r--release/datafiles/splash_2x.pngbin632582 -> 444285 bytes
-rw-r--r--release/freedesktop/blender.desktop71
m---------release/scripts/addons0
m---------release/scripts/addons_contrib0
-rw-r--r--release/scripts/modules/bl_i18n_utils/bl_extract_messages.py5
-rw-r--r--release/scripts/modules/bl_i18n_utils/settings.py11
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py4
-rw-r--r--release/scripts/modules/bl_previews_utils/bl_previews_render.py491
-rw-r--r--release/scripts/modules/bpy/path.py28
-rw-r--r--release/scripts/modules/bpy/utils/__init__.py59
-rw-r--r--release/scripts/modules/bpy_extras/anim_utils.py18
-rw-r--r--release/scripts/modules/bpy_extras/image_utils.py12
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py31
-rw-r--r--release/scripts/modules/nodeitems_utils.py2
-rw-r--r--release/scripts/modules/progress_report.py3
-rw-r--r--release/scripts/modules/rna_prop_ui.py5
-rw-r--r--release/scripts/modules/sys_info.py119
-rw-r--r--release/scripts/startup/bl_operators/__init__.py1
-rw-r--r--release/scripts/startup/bl_operators/file.py244
-rw-r--r--release/scripts/startup/bl_operators/node.py2
-rw-r--r--release/scripts/startup/bl_operators/wm.py21
-rw-r--r--release/scripts/startup/bl_ui/properties_data_armature.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_freestyle.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_game.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_render_layer.py1
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py7
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py51
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py4
-rw-r--r--release/scripts/startup/bl_ui/space_image.py11
-rw-r--r--release/scripts/startup/bl_ui/space_info.py6
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py7
-rw-r--r--release/scripts/startup/bl_ui/space_time.py2
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py5
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py4
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py2
52 files changed, 1434 insertions, 177 deletions
diff --git a/release/bin/blender-thumbnailer.py b/release/bin/blender-thumbnailer.py
index d3b31d63fad..fe5d462bba9 100755
--- a/release/bin/blender-thumbnailer.py
+++ b/release/bin/blender-thumbnailer.py
@@ -88,9 +88,8 @@ def blend_extract_thumb(path):
import os
open_wrapper = open_wrapper_get()
- # def MAKE_ID(tag): ord(tag[0])<<24 | ord(tag[1])<<16 | ord(tag[2])<<8 | ord(tag[3])
- REND = 1145980242 # MAKE_ID(b'REND')
- TEST = 1414743380 # MAKE_ID(b'TEST')
+ REND = b'REND'
+ TEST = b'TEST'
blendfile = open_wrapper(path, 'rb')
@@ -116,7 +115,8 @@ def blend_extract_thumb(path):
return None, 0, 0
sizeof_bhead = 24 if is_64_bit else 20
- int_endian_pair = '>ii' if is_big_endian else '<ii'
+ int_endian = '>i' if is_big_endian else '<i'
+ int_endian_pair = int_endian + 'i'
while True:
bhead = blendfile.read(sizeof_bhead)
@@ -124,7 +124,8 @@ def blend_extract_thumb(path):
if len(bhead) < sizeof_bhead:
return None, 0, 0
- code, length = struct.unpack(int_endian_pair, bhead[0:8]) # 8 == sizeof(int) * 2
+ code = bhead[:4]
+ length = struct.unpack(int_endian, bhead[4:8])[0] # 4 == sizeof(int)
if code == REND:
blendfile.seek(length, os.SEEK_CUR)
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
index 94784a73782..40b974661fa 100644
--- a/release/datafiles/blender_icons.svg
+++ b/release/datafiles/blender_icons.svg
@@ -30748,6 +30748,215 @@
offset="1"
id="stop16000-1" />
</linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16023"
+ id="radialGradient16031"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="7"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16023">
+ <stop
+ style="stop-color:#d8d8d8;stop-opacity:1"
+ offset="0"
+ id="stop16025" />
+ <stop
+ style="stop-color:#9a9a9a;stop-opacity:1"
+ offset="1"
+ id="stop16027" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16023"
+ id="radialGradient14148"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="7"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16023"
+ id="radialGradient14156"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="7"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16023"
+ id="radialGradient14164"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="7"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16023"
+ id="radialGradient14172"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="7"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16023"
+ id="radialGradient14180"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="7"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15984"
+ id="radialGradient15990"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="1"
+ gradientTransform="matrix(14.5,0,0,5.5,-1876.5,-618.75)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient15984">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop15986" />
+ <stop
+ style="stop-color:#a8cafb;stop-opacity:1"
+ offset="1"
+ id="stop15988" />
+ </linearGradient>
+ <radialGradient
+ r="7"
+ fy="137.5"
+ fx="139"
+ cy="137.5"
+ cx="139"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient14206"
+ xlink:href="#linearGradient16023"
+ inkscape:collect="always" />
+ <radialGradient
+ r="7"
+ fy="137.5"
+ fx="139"
+ cy="137.5"
+ cx="139"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient14208"
+ xlink:href="#linearGradient16023"
+ inkscape:collect="always" />
+ <radialGradient
+ r="7"
+ fy="137.5"
+ fx="139"
+ cy="137.5"
+ cx="139"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient14210"
+ xlink:href="#linearGradient16023"
+ inkscape:collect="always" />
+ <radialGradient
+ r="7"
+ fy="137.5"
+ fx="139"
+ cy="137.5"
+ cx="139"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient14212"
+ xlink:href="#linearGradient16023"
+ inkscape:collect="always" />
+ <radialGradient
+ r="7"
+ fy="137.5"
+ fx="139"
+ cy="137.5"
+ cx="139"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.07143,68.75)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient14214"
+ xlink:href="#linearGradient16023"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1"
+ fy="137.5"
+ fx="139"
+ cy="137.5"
+ cx="139"
+ gradientTransform="matrix(14.5,0,0,5.5,-1876.5,-618.75)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient14216"
+ xlink:href="#linearGradient15984"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16023"
+ id="radialGradient16945"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-129.59176,68.75)"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="7" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16023"
+ id="radialGradient16947"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.9285714,0,0,0.5,-128.51641,68.75)"
+ cx="139"
+ cy="137.5"
+ fx="139"
+ fy="137.5"
+ r="7" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610"
+ id="linearGradient31208"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-41,98)"
+ x1="-170.25"
+ y1="65.5"
+ x2="-181.375"
+ y2="65.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient31210"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.2857143,0,0,0.787037,-92.714287,177.80092)"
+ x1="-101"
+ y1="-16"
+ x2="-93.75"
+ y2="-16.264704" />
</defs>
<sodipodi:namedview
id="base"
@@ -91625,8 +91834,146 @@
style="opacity:0.51799999;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 316.57643,242.95337 c 0,0.33872 -0.26469,0.6133 -0.5912,0.6133 -0.32651,0 -0.5912,-0.27458 -0.5912,-0.6133 0,-0.33872 0.26469,-0.6133 0.5912,-0.6133 0.32651,0 0.5912,0.27458 0.5912,0.6133 z" />
</g>
+ <g
+ transform="translate(189.00803,-79.37555)"
+ style="display:inline;enable-background:new"
+ id="g14119">
+ <g
+ id="g16949">
+ <rect
+ style="color:#000000;fill:#272727;fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect15992"
+ width="2"
+ height="7"
+ x="134.47968"
+ y="134"
+ ry="1" />
+ <rect
+ style="color:#000000;fill:#272727;fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect15994"
+ width="2"
+ height="7"
+ x="141.55502"
+ y="134"
+ ry="1" />
+ <rect
+ ry="1"
+ y="136"
+ x="131.25"
+ height="3"
+ width="15.5"
+ id="rect15926"
+ style="color:#000000;fill:#272727;fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ ry="1"
+ y="132.25"
+ x="131.25"
+ height="10.5"
+ width="2.5"
+ id="rect15930"
+ style="color:#000000;fill:#272727;fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ ry="1"
+ y="132.25"
+ x="144.25"
+ height="10.5"
+ width="2.5"
+ id="rect15938"
+ style="color:#000000;fill:#272727;fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <g
+ id="g16016-6"
+ style="fill:url(#radialGradient16031);fill-opacity:1">
+ <rect
+ style="color:#000000;fill:url(#radialGradient14206);fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect15946"
+ width="1"
+ height="9"
+ x="132"
+ y="133"
+ ry="0.5" />
+ <rect
+ style="color:#000000;fill:url(#radialGradient14208);fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect15946-7"
+ width="1"
+ height="9"
+ x="145"
+ y="133"
+ ry="0.5" />
+ <rect
+ ry="0.5"
+ y="137"
+ x="132"
+ height="1"
+ width="14"
+ id="rect15972"
+ style="color:#000000;fill:url(#radialGradient14210);fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ ry="1"
+ y="135"
+ x="134.97968"
+ height="5"
+ width="1"
+ id="rect15996"
+ style="color:#000000;fill:url(#radialGradient16945);fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ <rect
+ ry="1"
+ y="135"
+ x="142.05502"
+ height="5"
+ width="1"
+ id="rect15998"
+ style="color:#000000;fill:url(#radialGradient16947);fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ </g>
+ <rect
+ style="opacity:0.51499999;color:#000000;fill:#0065ff;fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="rect15974"
+ width="4"
+ height="11"
+ x="137"
+ y="132"
+ ry="1" />
+ <rect
+ ry="1"
+ y="133"
+ x="138"
+ height="9"
+ width="2"
+ id="rect15944"
+ style="color:#000000;fill:url(#radialGradient14216);fill-opacity:1;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
+ </g>
+ </g>
</g>
</g>
+ <g
+ style="display:inline;enable-background:new"
+ id="ICON_MESH_CAPSULE"
+ transform="matrix(0.86967262,0,0,0.81949894,414.30767,262.03112)">
+ <rect
+ y="155"
+ x="-228"
+ height="16"
+ width="16"
+ id="rect41297-1"
+ style="display:inline;overflow:visible;visibility:visible;opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccsccc"
+ id="path41299-4"
+ d="m -220,154.54901 c -3.036,0 -5.49999,3.07099 -5.49999,4.45099 l -1e-5,9 c 0,1.38 2.46399,4.41118 5.49999,4.41118 3.036,0 5.5,-3.03118 5.5,-4.41118 l 1e-5,-9 c 0,-1.38 -2.464,-4.45099 -5.5,-4.45099 z"
+ style="display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient31208);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ style="display:inline;overflow:visible;visibility:visible;fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:7.40000248;stroke-opacity:1;marker:none;enable-background:accumulate"
+ d="m -220,154.19066 c -3.49999,0 -5.36123,3.42934 -5.36123,4.80934 l -1e-5,8.5 c 0,2 2.32523,5.30934 5.36123,5.30934 3.036,0 5.36125,-3.30934 5.36125,-5.30934 l 0,-8.5 c 0,-1.38 -1.86123,-4.80934 -5.36124,-4.80934 z"
+ id="path41305-2"
+ sodipodi:nodetypes="cccsccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="display:inline;overflow:visible;visibility:visible;fill:none;stroke:url(#linearGradient31210);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:7.40000248;stroke-opacity:1;marker:none;enable-background:accumulate"
+ d="m -224.5,160.5 0,6.5 c 0,0.9838 0.60816,4.76952 4.46531,4.76952 3.85714,0 4.53469,-3.78572 4.53469,-4.76952 l 0,-6.5 c 0,0 0.43828,-5.18967 -4.47408,-5.25396 C -224.88644,155.18174 -224.5,160.5 -224.5,160.5 Z"
+ id="path41307-2"
+ sodipodi:nodetypes="ccsccsc"
+ inkscape:connector-curvature="0" />
+ </g>
</g>
<g
inkscape:groupmode="layer"
diff --git a/release/datafiles/blender_icons16/icon16_library_data_broken.dat b/release/datafiles/blender_icons16/icon16_library_data_broken.dat
index e0ede6bc019..613fac48c21 100644
--- a/release/datafiles/blender_icons16/icon16_library_data_broken.dat
+++ b/release/datafiles/blender_icons16/icon16_library_data_broken.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_mesh_capsule.dat b/release/datafiles/blender_icons16/icon16_mesh_capsule.dat
new file mode 100644
index 00000000000..031cac70eea
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_mesh_capsule.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_snap_grid.dat b/release/datafiles/blender_icons16/icon16_snap_grid.dat
new file mode 100644
index 00000000000..4def9b8df2e
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_snap_grid.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_snap_increment.dat b/release/datafiles/blender_icons16/icon16_snap_increment.dat
index 4def9b8df2e..5216afb6d72 100644
--- a/release/datafiles/blender_icons16/icon16_snap_increment.dat
+++ b/release/datafiles/blender_icons16/icon16_snap_increment.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_library_data_broken.dat b/release/datafiles/blender_icons32/icon32_library_data_broken.dat
index e1ec782d5f4..89702a9ff9e 100644
--- a/release/datafiles/blender_icons32/icon32_library_data_broken.dat
+++ b/release/datafiles/blender_icons32/icon32_library_data_broken.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_mesh_capsule.dat b/release/datafiles/blender_icons32/icon32_mesh_capsule.dat
new file mode 100644
index 00000000000..213ef4281e1
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_mesh_capsule.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_snap_grid.dat b/release/datafiles/blender_icons32/icon32_snap_grid.dat
new file mode 100644
index 00000000000..cc4c0efe3c4
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_snap_grid.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_snap_increment.dat b/release/datafiles/blender_icons32/icon32_snap_increment.dat
index cc4c0efe3c4..eb88877e3ad 100644
--- a/release/datafiles/blender_icons32/icon32_snap_increment.dat
+++ b/release/datafiles/blender_icons32/icon32_snap_increment.dat
Binary files differ
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject c651e63a9a537624f639950f3127a1dee29205d
+Subproject e4d4a560cafb21d74dd4db13473a2d1d7ee7316
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index cfadec07b09..f84f092d5f8 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/datafiles/splash_2x.png b/release/datafiles/splash_2x.png
index 79a6f2781ff..f4c611c8cc1 100644
--- a/release/datafiles/splash_2x.png
+++ b/release/datafiles/splash_2x.png
Binary files differ
diff --git a/release/freedesktop/blender.desktop b/release/freedesktop/blender.desktop
index a28a8155121..d661a157bfb 100644
--- a/release/freedesktop/blender.desktop
+++ b/release/freedesktop/blender.desktop
@@ -1,14 +1,83 @@
[Desktop Entry]
Name=Blender
GenericName=3D modeler
+GenericName[ar]=3D المنمذج ثلاثي الأبعاد
+GenericName[ca]=Modelador 3D
+GenericName[cs]=3D modelování
+GenericName[da]=3D-modellering
GenericName[de]=3D-Modellierer
+GenericName[el]=Μοντελοποιητής 3D
GenericName[es]=Modelador 3D
+GenericName[et]=3D modelleerija
+GenericName[fi]=3D-mallintaja
GenericName[fr]=Modeleur 3D
+GenericName[gl]=Modelador 3D
+GenericName[hu]=3D modellező
+GenericName[it]=Modellatore 3D
+GenericName[ja]=3D モデラー
+GenericName[lt]=3D modeliavimas
+GenericName[nb]=3D-modellering
+GenericName[nl]=3D-modeller
+GenericName[pl]=Modelowanie 3D
+GenericName[pt_BR]=Modelador 3D
+GenericName[ro]=Arhitect 3D
GenericName[ru]=Редактор 3D-моделей
+GenericName[tr]=3D modelleyici
+GenericName[uk]=Редактор 3D-моделей
+GenericName[wa]=Modeleu 3D
+GenericName[zh_CN]=3D 建模
+GenericName[zh_TW]=3D 模型
Comment=3D modeling, animation, rendering and post-production
+Comment[ar]=3D النمذجة، الرسوم المتحركة، والتجسيد، وما بعد الإنتاج
+Comment[ast]=Modeláu 3D, animación, renderizáu y postproducción
+Comment[eu]=3D modelatzea, animazioa, errendatzea eta post-produkzioa
+Comment[be]=Праграма прасторавага мадэлявання, анімацыі, апрацоўкі відэа і давядзення відэапрадукцыі
+Comment[bn]=ত্রিমাত্রিক মডেল, অ্যানিমেশন, রেন্ডারিং এবং পোস্ট-উৎপাদন
+Comment[bs]=3D modeliranje, animacija, obrada i postprodukcija
+Comment[bg]=3D моделиране, анимиране, рендиране и пост-продукция
+Comment[ca]=Modelat 3D, animació, renderització i post-producció
+Comment[ca@valencia]=Modelat 3D, animació, renderització i post-producció
+Comment[crh]=3B modelleme, animasyon, işleme ve son üretim
+Comment[cs]=3D modelování, animace, rederování a postprodukce
+Comment[da]=3D-modellering, animation, rendering og efterbehandling
Comment[de]=3D-Modellierung, Animation, Rendering und Nachbearbeitung
+Comment[nl]=3d-modelleren, animeren, renderen en post-productie
+Comment[el]=Μοντελοποίηση 3D, κινούμενα σχέδια, αποτύπωση και οργάνωση διαδικασίας μετά-την-παραγωγή
+Comment[eo]=3D-modelado, animacio, renderado kaj postproduktado
Comment[es]=Modelado 3D, animación, renderizado y post-producción
-Comment[fr]=Modelage 3D, animation, rendu et post-production
+Comment[et]=Kolmemõõtmeline modelleerimine, animeerimine, esitlemine ja järeltöötlemine
+Comment[fi]=3D-mallinnus, -animaatiot, -renderöinti ja -tuotanto
+Comment[fr]=Modélisation 3D, animation, rendu et post-production
+Comment[fr_CA]=Modélisation 3D, animation, rendu et post-production
+Comment[gl]=Modelado 3D, animación, renderizado e postprodución
+Comment[hu]=3D modellek és animációk létrehozása és szerkesztése
+Comment[is]=Þrívíddarmódel, hreyfimyndir, myndgerð og frágangur myndskeiða
+Comment[it]=Modellazione 3D, animazione, rendering e post-produzione
+Comment[ja]=3Dモデリング、アニメーション、レンダリング、ポストプロダクションのツール
+Comment[ko]=3D 모델링, 애니메이션, 렌더링과 포스트 프로덕션
+Comment[lt]=3D modeliavimas, animacijų kūrimas, atvaizdavimas ir tobulinimas
+Comment[lv]=3D modelēšana, animācija, renderēšana un pēcapstrāde
+Comment[ms]=Pemodelan, animasi, penerapan dan post-produksi 3D
+Comment[nb]=3D-modellering, animasjon, rendering og postproduksjon
+Comment[oc]=Modelizacion 3D, animacion, rendut e post-produccion
+Comment[pl]=Modelowanie 3D, animacja, renderowanie i postprodukcja
+Comment[pt]=Modelação 3D, animação, renderização e pós-produção
+Comment[pt_BR]=Modelagem 3D, animação, renderização e pós-produção
+Comment[ro]=Modelare, animare, afișare și post-producție 3D
+Comment[ru]=3D-моделирование, анимация, рендеринг и компоновка
+Comment[sl]=3D modeliranje, animacija, izrisovanje in nadaljnje obdelovanje
+Comment[sq]=Animacion i modeleve 3D, rregullim dhe më pas prodhim
+Comment[sr]=3Д моделовање, анимација, исцртавање и постпродукција
+Comment[sv]=3d-modellering, animering, rendering och efterbehandling
+Comment[ta]=முப்பரிமாண ஒப்புருவாக்கம், அசைவூட்டம், காட்சியாக்கம் மற்றும் உருவாக்கத்துக்கு பிந்தைய செயல்பாடுகள்
+Comment[tg]=Моделсозии 3D, аниматсия, пешниҳод ва истеҳсоли баъдӣ
+Comment[tr]=3B modelleme, animasyon, işleme ve son üretim
+Comment[uk]=Програма просторового моделювання, анімації, обробки відео та доведення відеопродуктів
+Comment[vi]=Tạo hình mẫu 3D, hoạt họa, dựng hình và các công việc hậu kỳ
+Comment[wa]=Modelaedje 3D, animåcion, rindou eyet après-produccion
+Comment[zh_HK]=3D 模型、動畫、算圖和後製
+Comment[zh_CN]=3D 建模、动画、渲染和后期制作
+Comment[zh_TW]=3D 模型、動畫、算圖和後製
Keywords=3d;cg;modeling;animation;painting;sculpting;texturing;video editing;video tracking;rendering;render engine;cycles;game engine;python;
Exec=blender %f
Icon=blender
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 3fc5b82c6bdba2f9c954fbf497621b9bb794a1b
+Subproject ecdc7c03ec14e6ed70dea808b61049017f46ad9
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
-Subproject cf842d8bb7b0033ca4fa99f7ebedcbd3810fd27
+Subproject c63ada6ae2569864be891ff308cda6b39d8368f
diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
index 43a09a1acbd..baa9140aaef 100644
--- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
+++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
@@ -304,7 +304,8 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
else:
bl_rna_base_props = set()
- for prop in bl_rna.properties:
+ props = sorted(bl_rna.properties, key=lambda p: p.identifier)
+ for prop in props:
# Only write this property if our parent hasn't got it.
if prop in bl_rna_base_props:
continue
@@ -456,7 +457,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
def extract_strings_split(node):
"""
- Returns a list args as returned by 'extract_strings()', But split into groups based on separate_nodes, this way
+ Returns a list args as returned by 'extract_strings()', but split into groups based on separate_nodes, this way
expressions like ("A" if test else "B") wont be merged but "A" + "B" will.
"""
estr_ls = []
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index a63633d25aa..49dbfbe62af 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -184,15 +184,15 @@ DOMAIN = "blender"
# File type (ext) to parse.
PYGETTEXT_ALLOWED_EXTS = {".c", ".cpp", ".cxx", ".hpp", ".hxx", ".h"}
-# Max number of contexts into a BLF_I18N_MSGID_MULTI_CTXT macro...
+# Max number of contexts into a BLT_I18N_MSGID_MULTI_CTXT macro...
PYGETTEXT_MAX_MULTI_CTXT = 16
# Where to search contexts definitions, relative to SOURCE_DIR (defined below).
-PYGETTEXT_CONTEXTS_DEFSRC = os.path.join("source", "blender", "blenfont", "BLF_translation.h")
+PYGETTEXT_CONTEXTS_DEFSRC = os.path.join("source", "blender", "blentranslation", "BLT_translation.h")
-# Regex to extract contexts defined in BLF_translation.h
+# Regex to extract contexts defined in BLT_translation.h
# XXX Not full-proof, but should be enough here!
-PYGETTEXT_CONTEXTS = "#define\\s+(BLF_I18NCONTEXT_[A-Z_0-9]+)\\s+\"([^\"]*)\""
+PYGETTEXT_CONTEXTS = "#define\\s+(BLT_I18NCONTEXT_[A-Z_0-9]+)\\s+\"([^\"]*)\""
# Keywords' regex.
# XXX Most unfortunately, we can't use named backreferences inside character sets,
@@ -255,7 +255,7 @@ PYGETTEXT_KEYWORDS = (() +
tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" +
r"\s*,\s*)?(?:".join(_ctxt_re_gen(i) for i in range(PYGETTEXT_MAX_MULTI_CTXT)) + r")?\s*\)").format(it)
- for it in ("BLF_I18N_MSGID_MULTI_CTXT",))
+ for it in ("BLT_I18N_MSGID_MULTI_CTXT",))
)
# Check printf mismatches between msgid and msgstr.
@@ -333,6 +333,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"expected a view3d region & editcurve",
"expected a view3d region & editmesh",
"image file not found",
+ "image format is read-only",
"image path can't be written to",
"in memory to enable editing!",
"jumps over",
diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
index e2f2aeef7b2..b1aa4e02cee 100644
--- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
@@ -97,6 +97,7 @@ class SpellChecker:
"denoise",
"deselect", "deselecting", "deselection",
"despill", "despilling",
+ "dirtree",
"editcurve",
"editmesh",
"filebrowser",
@@ -113,7 +114,7 @@ class SpellChecker:
"libdata",
"lightless",
"lineset",
- "linestyle",
+ "linestyle", "linestyles",
"localview",
"lookup", "lookups",
"mathutils",
@@ -128,6 +129,7 @@ class SpellChecker:
"multiuser",
"multiview",
"namespace",
+ "nodetree", "nodetrees",
"keyconfig",
"online",
"playhead",
diff --git a/release/scripts/modules/bl_previews_utils/bl_previews_render.py b/release/scripts/modules/bl_previews_utils/bl_previews_render.py
new file mode 100644
index 00000000000..627a6ab2d3d
--- /dev/null
+++ b/release/scripts/modules/bl_previews_utils/bl_previews_render.py
@@ -0,0 +1,491 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# <pep8 compliant>
+
+# Populate a template file (POT format currently) from Blender RNA/py/C data.
+# Note: This script is meant to be used from inside Blender!
+
+import collections
+import os
+import sys
+
+import bpy
+from mathutils import Vector, Euler
+
+
+INTERN_PREVIEW_TYPES = {'MATERIAL', 'LAMP', 'WORLD', 'TEXTURE', 'IMAGE'}
+OBJECT_TYPES_RENDER = {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'}
+
+
+def ids_nolib(bids):
+ return (bid for bid in bids if not bid.library)
+
+
+def rna_backup_gen(data, include_props=None, exclude_props=None, root=()):
+ # only writable properties...
+ for p in data.bl_rna.properties:
+ pid = p.identifier
+ if pid in {'rna_type', }:
+ continue
+ path = root + (pid,)
+ if include_props is not None and path not in include_props:
+ continue
+ if exclude_props is not None and path in exclude_props:
+ continue
+ val = getattr(data, pid)
+ if val is not None and p.type == 'POINTER':
+ # recurse!
+ yield from rna_backup_gen(val, include_props, exclude_props, root=path)
+ elif data.is_property_readonly(pid):
+ continue
+ else:
+ yield path, val
+
+
+def rna_backup_restore(data, backup):
+ for path, val in backup:
+ dt = data
+ for pid in path[:-1]:
+ dt = getattr(dt, pid)
+ setattr(dt, path[-1], val)
+
+
+def do_previews(do_objects, do_groups, do_scenes, do_data_intern):
+ # Helpers.
+ RenderContext = collections.namedtuple("RenderContext", (
+ "scene", "world", "camera", "lamp", "camera_data", "lamp_data", "image", # All those are names!
+ "backup_scene", "backup_world", "backup_camera", "backup_lamp", "backup_camera_data", "backup_lamp_data",
+ ))
+
+ RENDER_PREVIEW_SIZE = bpy.app.render_preview_size
+
+ def render_context_create(engine, objects_ignored):
+ if engine == '__SCENE':
+ backup_scene, backup_world, backup_camera, backup_lamp, backup_camera_data, backup_lamp_data = [()] * 6
+ scene = bpy.context.screen.scene
+ exclude_props = {('world',), ('camera',), ('tool_settings',), ('preview',)}
+ backup_scene = tuple(rna_backup_gen(scene, exclude_props=exclude_props))
+ world = scene.world
+ camera = scene.camera
+ if camera:
+ camera_data = camera.data
+ else:
+ backup_camera, backup_camera_data = [None] * 2
+ camera_data = bpy.data.cameras.new("TEMP_preview_render_camera")
+ camera = bpy.data.objects.new("TEMP_preview_render_camera", camera_data)
+ camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ') # (66.67, 0.0, 45.0)
+ scene.camera = camera
+ scene.objects.link(camera)
+ # TODO: add lamp if none found in scene?
+ lamp = None
+ lamp_data = None
+ else:
+ backup_scene, backup_world, backup_camera, backup_lamp, backup_camera_data, backup_lamp_data = [None] * 6
+
+ scene = bpy.data.scenes.new("TEMP_preview_render_scene")
+ world = bpy.data.worlds.new("TEMP_preview_render_world")
+ camera_data = bpy.data.cameras.new("TEMP_preview_render_camera")
+ camera = bpy.data.objects.new("TEMP_preview_render_camera", camera_data)
+ lamp_data = bpy.data.lamps.new("TEMP_preview_render_lamp", 'SPOT')
+ lamp = bpy.data.objects.new("TEMP_preview_render_lamp", lamp_data)
+
+ objects_ignored.add((camera.name, lamp.name))
+
+ scene.world = world
+
+ camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ') # (66.67, 0.0, 45.0)
+ scene.camera = camera
+ scene.objects.link(camera)
+
+ lamp.rotation_euler = Euler((0.7853981852531433, 0.0, 1.7453292608261108), 'XYZ') # (45.0, 0.0, 100.0)
+ lamp_data.falloff_type = 'CONSTANT'
+ lamp_data.spot_size = 1.0471975803375244 # 60
+ scene.objects.link(lamp)
+
+ if engine == 'BLENDER_RENDER':
+ scene.render.engine = 'BLENDER_RENDER'
+ scene.render.alpha_mode = 'TRANSPARENT'
+
+ world.use_sky_blend = True
+ world.horizon_color = 0.9, 0.9, 0.9
+ world.zenith_color = 0.5, 0.5, 0.5
+ world.ambient_color = 0.1, 0.1, 0.1
+ world.light_settings.use_environment_light = True
+ world.light_settings.environment_energy = 1.0
+ world.light_settings.environment_color = 'SKY_COLOR'
+ elif engine == 'CYCLES':
+ scene.render.engine = 'CYCLES'
+ scene.cycles.film_transparent = True
+ # TODO: define Cycles world?
+
+ scene.render.image_settings.file_format = 'PNG'
+ scene.render.image_settings.color_depth = '8'
+ scene.render.image_settings.color_mode = 'RGBA'
+ scene.render.image_settings.compression = 25
+ scene.render.resolution_x = RENDER_PREVIEW_SIZE
+ scene.render.resolution_y = RENDER_PREVIEW_SIZE
+ scene.render.resolution_percentage = 100
+ scene.render.filepath = os.path.join(bpy.app.tempdir, 'TEMP_preview_render.png')
+ scene.render.use_overwrite = True
+ scene.render.use_stamp = False
+
+ image = bpy.data.images.new("TEMP_render_image", RENDER_PREVIEW_SIZE, RENDER_PREVIEW_SIZE, alpha=True)
+ image.source = 'FILE'
+ image.filepath = scene.render.filepath
+
+ return RenderContext(
+ scene.name, world.name if world else None, camera.name, lamp.name if lamp else None,
+ camera_data.name, lamp_data.name if lamp_data else None, image.name,
+ backup_scene, backup_world, backup_camera, backup_lamp, backup_camera_data, backup_lamp_data,
+ )
+
+ def render_context_delete(render_context):
+ # We use try/except blocks here to avoid crash, too much things can go wrong, and we want to leave the current
+ # .blend as clean as possible!
+ success = True
+
+ scene = bpy.data.scenes[render_context.scene, None]
+ try:
+ if render_context.backup_scene is None:
+ scene.world = None
+ scene.camera = None
+ if render_context.camera:
+ scene.objects.unlink(bpy.data.objects[render_context.camera, None])
+ if render_context.lamp:
+ scene.objects.unlink(bpy.data.objects[render_context.lamp, None])
+ bpy.data.scenes.remove(scene)
+ scene = None
+ else:
+ rna_backup_restore(scene, render_context.backup_scene)
+ except Exception as e:
+ print("ERROR:", e)
+ success = False
+
+ if render_context.world is not None:
+ try:
+ world = bpy.data.worlds[render_context.world, None]
+ if render_context.backup_world is None:
+ if scene is not None:
+ scene.world = None
+ world.user_clear()
+ bpy.data.worlds.remove(world)
+ else:
+ rna_backup_restore(world, render_context.backup_world)
+ except Exception as e:
+ print("ERROR:", e)
+ success = False
+
+ if render_context.camera:
+ try:
+ camera = bpy.data.objects[render_context.camera, None]
+ if render_context.backup_camera is None:
+ if scene is not None:
+ scene.camera = None
+ scene.objects.unlink(camera)
+ camera.user_clear()
+ bpy.data.objects.remove(camera)
+ bpy.data.cameras.remove(bpy.data.cameras[render_context.camera_data, None])
+ else:
+ rna_backup_restore(camera, render_context.backup_camera)
+ rna_backup_restore(bpy.data.cameras[render_context.camera_data, None],
+ render_context.backup_camera_data)
+ except Exception as e:
+ print("ERROR:", e)
+ success = False
+
+ if render_context.lamp:
+ try:
+ lamp = bpy.data.objects[render_context.lamp, None]
+ if render_context.backup_lamp is None:
+ if scene is not None:
+ scene.objects.unlink(lamp)
+ lamp.user_clear()
+ bpy.data.objects.remove(lamp)
+ bpy.data.lamps.remove(bpy.data.lamps[render_context.lamp_data, None])
+ else:
+ rna_backup_restore(lamp, render_context.backup_lamp)
+ rna_backup_restore(bpy.data.lamps[render_context.lamp_data, None], render_context.backup_lamp_data)
+ except Exception as e:
+ print("ERROR:", e)
+ success = False
+
+ try:
+ image = bpy.data.images[render_context.image, None]
+ image.user_clear()
+ bpy.data.images.remove(image)
+ except Exception as e:
+ print("ERROR:", e)
+ success = False
+
+ return success
+
+ def objects_render_engine_guess(obs):
+ for obname in obs:
+ ob = bpy.data.objects[obname, None]
+ for matslot in ob.material_slots:
+ mat = matslot.material
+ if mat and mat.use_nodes and mat.node_tree:
+ for nd in mat.node_tree.nodes:
+ if nd.shading_compatibility == {'NEW_SHADING'}:
+ return 'CYCLES'
+ return 'BLENDER_RENDER'
+
+ def object_bbox_merge(bbox, ob, ob_space):
+ if ob.bound_box:
+ ob_bbox = ob.bound_box
+ else:
+ ob_bbox = ((-ob.scale.x, -ob.scale.y, -ob.scale.z), (ob.scale.x, ob.scale.y, ob.scale.z))
+ for v in ob.bound_box:
+ v = ob_space.matrix_world.inverted() * ob.matrix_world * Vector(v)
+ if bbox[0].x > v.x:
+ bbox[0].x = v.x
+ if bbox[0].y > v.y:
+ bbox[0].y = v.y
+ if bbox[0].z > v.z:
+ bbox[0].z = v.z
+ if bbox[1].x < v.x:
+ bbox[1].x = v.x
+ if bbox[1].y < v.y:
+ bbox[1].y = v.y
+ if bbox[1].z < v.z:
+ bbox[1].z = v.z
+
+ def objects_bbox_calc(camera, objects):
+ bbox = (Vector((1e9, 1e9, 1e9)), Vector((-1e9, -1e9, -1e9)))
+ for obname in objects:
+ ob = bpy.data.objects[obname, None]
+ object_bbox_merge(bbox, ob, camera)
+ # Our bbox has been generated in camera local space, bring it back in world one
+ bbox[0][:] = camera.matrix_world * bbox[0]
+ bbox[1][:] = camera.matrix_world * bbox[1]
+ cos = (
+ bbox[0].x, bbox[0].y, bbox[0].z,
+ bbox[0].x, bbox[0].y, bbox[1].z,
+ bbox[0].x, bbox[1].y, bbox[0].z,
+ bbox[0].x, bbox[1].y, bbox[1].z,
+ bbox[1].x, bbox[0].y, bbox[0].z,
+ bbox[1].x, bbox[0].y, bbox[1].z,
+ bbox[1].x, bbox[1].y, bbox[0].z,
+ bbox[1].x, bbox[1].y, bbox[1].z,
+ )
+ return cos
+
+ def preview_render_do(render_context, item_container, item_name, objects):
+ scene = bpy.data.scenes[render_context.scene, None]
+ if objects is not None:
+ camera = bpy.data.objects[render_context.camera, None]
+ lamp = bpy.data.objects[render_context.lamp, None] if render_context.lamp is not None else None
+ cos = objects_bbox_calc(camera, objects)
+ loc, ortho_scale = camera.camera_fit_coords(scene, cos)
+ camera.location = loc
+ if lamp:
+ loc, ortho_scale = lamp.camera_fit_coords(scene, cos)
+ lamp.location = loc
+ scene.update()
+
+ bpy.ops.render.render(write_still=True)
+
+ image = bpy.data.images[render_context.image, None]
+ item = getattr(bpy.data, item_container)[item_name, None]
+ image.reload()
+ item.preview.image_size = (RENDER_PREVIEW_SIZE, RENDER_PREVIEW_SIZE)
+ item.preview.image_pixels_float[:] = image.pixels
+
+ # And now, main code!
+ do_save = True
+
+ if do_data_intern:
+ bpy.ops.wm.previews_clear(id_type=INTERN_PREVIEW_TYPES)
+ bpy.ops.wm.previews_ensure()
+
+ render_contexts = {}
+
+ objects_ignored = set()
+ groups_ignored = set()
+
+ prev_scenename = bpy.context.screen.scene.name
+
+ if do_objects:
+ prev_shown = tuple(ob.hide_render for ob in ids_nolib(bpy.data.objects))
+ for ob in ids_nolib(bpy.data.objects):
+ if ob in objects_ignored:
+ continue
+ ob.hide_render = True
+ for root in ids_nolib(bpy.data.objects):
+ if root.name in objects_ignored:
+ continue
+ if root.type not in OBJECT_TYPES_RENDER:
+ continue
+ objects = (root.name,)
+
+ render_engine = objects_render_engine_guess(objects)
+ render_context = render_contexts.get(render_engine, None)
+ if render_context is None:
+ render_context = render_context_create(render_engine, objects_ignored)
+ render_contexts[render_engine] = render_context
+
+ scene = bpy.data.scenes[render_context.scene, None]
+ bpy.context.screen.scene = scene
+
+ for obname in objects:
+ ob = bpy.data.objects[obname, None]
+ if obname not in scene.objects:
+ scene.objects.link(ob)
+ ob.hide_render = False
+ scene.update()
+
+ preview_render_do(render_context, 'objects', root.name, objects)
+
+ # XXX Hyper Super Uber Suspicious Hack!
+ # Without this, on windows build, script excepts with following message:
+ # Traceback (most recent call last):
+ # File "<string>", line 1, in <module>
+ # File "<string>", line 451, in <module>
+ # File "<string>", line 443, in main
+ # File "<string>", line 327, in do_previews
+ # OverflowError: Python int too large to convert to C long
+ # ... :(
+ import sys
+ scene = bpy.data.scenes[render_context.scene, None]
+ for obname in objects:
+ ob = bpy.data.objects[obname, None]
+ scene.objects.unlink(ob)
+ ob.hide_render = True
+
+ for ob, is_rendered in zip(tuple(ids_nolib(bpy.data.objects)), prev_shown):
+ ob.hide_render = is_rendered
+
+ if do_groups:
+ for grp in ids_nolib(bpy.data.groups):
+ if grp.name in groups_ignored:
+ continue
+ objects = tuple(ob.name for ob in grp.objects)
+
+ render_engine = objects_render_engine_guess(objects)
+ render_context = render_contexts.get(render_engine, None)
+ if render_context is None:
+ render_context = render_context_create(render_engine, objects_ignored)
+ render_contexts[render_engine] = render_context
+
+ scene = bpy.data.scenes[render_context.scene, None]
+ bpy.context.screen.scene = scene
+
+ bpy.ops.object.group_instance_add(group=grp.name)
+ grp_ob = next((ob for ob in scene.objects if ob.dupli_group and ob.dupli_group.name == grp.name))
+ grp_obname = grp_ob.name
+ scene.update()
+
+ preview_render_do(render_context, 'groups', grp.name, objects)
+
+ scene = bpy.data.scenes[render_context.scene, None]
+ scene.objects.unlink(bpy.data.objects[grp_obname, None])
+
+ bpy.context.screen.scene = bpy.data.scenes[prev_scenename, None]
+ for render_context in render_contexts.values():
+ if not render_context_delete(render_context):
+ do_save = False # Do not save file if something went wrong here, we could 'pollute' it with temp data...
+
+ if do_scenes:
+ for scene in ids_nolib(bpy.data.scenes):
+ has_camera = scene.camera is not None
+ bpy.context.screen.scene = scene
+ render_context = render_context_create('__SCENE', objects_ignored)
+ scene.update()
+
+ objects = None
+ if not has_camera:
+ # We had to add a temp camera, now we need to place it to see interesting objects!
+ objects = tuple(ob.name for ob in scene.objects
+ if (not ob.hide_render) and (ob.type in OBJECT_TYPES_RENDER))
+
+ preview_render_do(render_context, 'scenes', scene.name, objects)
+
+ if not render_context_delete(render_context):
+ do_save = False
+
+ bpy.context.screen.scene = bpy.data.scenes[prev_scenename, None]
+ if do_save:
+ print("Saving %s..." % bpy.data.filepath)
+ try:
+ bpy.ops.wm.save_mainfile()
+ except Exception as e:
+ # Might fail in some odd cases, like e.g. in regression files we have glsl/ram_glsl.blend which
+ # references an inexistent texture... Better not break in this case, just spit error to console.
+ print("ERROR:", e)
+ else:
+ print("*NOT* Saving %s, because some error(s) happened while deleting temp render data..." % bpy.data.filepath)
+
+
+def do_clear_previews(do_objects, do_groups, do_scenes, do_data_intern):
+ if do_data_intern:
+ bpy.ops.wm.previews_clear(id_type=INTERN_PREVIEW_TYPES)
+
+ if do_objects:
+ for ob in ids_nolib(bpy.data.objects):
+ ob.preview.image_size = (0, 0)
+
+ if do_groups:
+ for grp in ids_nolib(bpy.data.groups):
+ grp.preview.image_size = (0, 0)
+
+ if do_scenes:
+ for scene in ids_nolib(bpy.data.scenes):
+ scene.preview.image_size = (0, 0)
+
+ print("Saving %s..." % bpy.data.filepath)
+ bpy.ops.wm.save_mainfile()
+
+
+def main():
+ try:
+ import bpy
+ except ImportError:
+ print("This script must run from inside blender")
+ return
+
+ import sys
+ import argparse
+
+ # Get rid of Blender args!
+ argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+
+ parser = argparse.ArgumentParser(description="Use Blender to generate previews for currently open Blender file's items.")
+ parser.add_argument('--clear', default=False, action="store_true", help="Clear previews instead of generating them.")
+ parser.add_argument('--no_scenes', default=True, action="store_false", help="Do not generate/clear previews for scene IDs.")
+ parser.add_argument('--no_groups', default=True, action="store_false", help="Do not generate/clear previews for group IDs.")
+ parser.add_argument('--no_objects', default=True, action="store_false", help="Do not generate/clear previews for object IDs.")
+ parser.add_argument('--no_data_intern', default=True, action="store_false",
+ help="Do not generate/clear previews for mat/tex/image/etc. IDs (those handled by core Blender code).")
+ args = parser.parse_args(argv)
+
+ if args.clear:
+ print("clear!")
+ do_clear_previews(do_objects=args.no_objects, do_groups=args.no_groups, do_scenes=args.no_scenes,
+ do_data_intern=args.no_data_intern)
+ else:
+ print("render!")
+ do_previews(do_objects=args.no_objects, do_groups=args.no_groups, do_scenes=args.no_scenes,
+ do_data_intern=args.no_data_intern)
+
+
+if __name__ == "__main__":
+ print("\n\n *** Running {} *** \n".format(__file__))
+ print(" *** Blend file {} *** \n".format(bpy.data.filepath))
+ main()
+ bpy.ops.wm.quit_blender()
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index d5b64933165..d7c6101115d 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -61,7 +61,7 @@ def abspath(path, start=None, library=None):
:arg start: Relative to this path,
when not set the current filename is used.
- :type start: string
+ :type start: string or bytes
:arg library: The library this path is from. This is only included for
convenience, when the library is not None its path replaces *start*.
:type library: :class:`bpy.types.Library`
@@ -90,9 +90,11 @@ def relpath(path, start=None):
"""
Returns the path relative to the current blend file using the "//" prefix.
+ :arg path: An absolute path.
+ :type path: string or bytes
:arg start: Relative to this path,
when not set the current filename is used.
- :type start: string
+ :type start: string or bytes
"""
if isinstance(path, bytes):
if not path.startswith(b"//"):
@@ -112,6 +114,9 @@ def is_subdir(path, directory):
"""
Returns true if *path* in a subdirectory of *directory*.
Both paths must be absolute.
+
+ :arg path: An absolute path.
+ :type path: string or bytes
"""
from os.path import normpath, normcase
path = normpath(normcase(path))
@@ -129,7 +134,7 @@ def clean_name(name, replace="_"):
may cause problems under various circumstances,
such as writing to a file.
All characters besides A-Z/a-z, 0-9 are replaced with "_"
- or the replace argument if defined.
+ or the *replace* argument if defined.
"""
if replace != "_":
@@ -278,22 +283,21 @@ def ensure_ext(filepath, ext, case_sensitive=False):
"""
Return the path with the extension added if it is not already set.
- :arg ext: The extension to check for.
+ :arg ext: The extension to check for, can be a compound extension. Should
+ start with a dot, such as '.blend' or '.tar.gz'.
:type ext: string
:arg case_sensitive: Check for matching case when comparing extensions.
:type case_sensitive: bool
"""
- fn_base, fn_ext = _os.path.splitext(filepath)
- if fn_base and fn_ext:
- if ((case_sensitive and ext == fn_ext) or
- (ext.lower() == fn_ext.lower())):
+ if case_sensitive:
+ if filepath.endswith(ext):
return filepath
- else:
- return fn_base + ext
-
else:
- return filepath + ext
+ if filepath[-len(ext):].lower().endswith(ext.lower()):
+ return filepath
+
+ return filepath + ext
def module_names(path, recursive=False):
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 7a1224db226..481db4659af 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -377,46 +377,31 @@ def preset_paths(subdir):
def smpte_from_seconds(time, fps=None):
"""
- Returns an SMPTE formatted string from the time in seconds: "HH:MM:SS:FF".
+ Returns an SMPTE formatted string from the *time*:
+ ``HH:MM:SS:FF``.
If the *fps* is not given the current scene is used.
- """
- import math
-
- if fps is None:
- fps = _bpy.context.scene.render.fps
-
- hours = minutes = seconds = frames = 0
-
- if time < 0:
- time = - time
- neg = "-"
- else:
- neg = ""
-
- if time >= 3600.0: # hours
- hours = int(time / 3600.0)
- time = time % 3600.0
- if time >= 60.0: # minutes
- minutes = int(time / 60.0)
- time = time % 60.0
- seconds = int(time)
- frames = int(round(math.floor(((time - seconds) * fps))))
+ :arg time: time in seconds.
+ :type time: int, float or ``datetime.timedelta``.
+ :return: the frame string.
+ :rtype: string
+ """
- return "%s%02d:%02d:%02d:%02d" % (neg, hours, minutes, seconds, frames)
+ return smpte_from_frame(time_to_frame(time, fps=fps), fps)
def smpte_from_frame(frame, fps=None, fps_base=None):
"""
- Returns an SMPTE formatted string from the frame: "HH:MM:SS:FF".
+ Returns an SMPTE formatted string from the *frame*:
+ ``HH:MM:SS:FF``.
If *fps* and *fps_base* are not given the current scene is used.
- :arg time: time in seconds.
- :type time: number or timedelta object
- :return: the frame.
- :rtype: float
+ :arg frame: frame number.
+ :type frame: int or float.
+ :return: the frame string.
+ :rtype: string
"""
if fps is None:
@@ -425,7 +410,17 @@ def smpte_from_frame(frame, fps=None, fps_base=None):
if fps_base is None:
fps_base = _bpy.context.scene.render.fps_base
- return smpte_from_seconds((frame * fps_base) / fps, fps)
+ sign = "-" if frame < 0 else ""
+ frame = abs(frame * fps_base)
+
+ return (
+ "%s%02d:%02d:%02d:%02d" % (
+ sign,
+ int(frame / (3600 * fps)), # HH
+ int((frame / (60 * fps)) % 60), # MM
+ int((frame / fps) % 60), # SS
+ int(frame % fps), # FF
+ ))
def time_from_frame(frame, fps=None, fps_base=None):
@@ -435,7 +430,7 @@ def time_from_frame(frame, fps=None, fps_base=None):
If *fps* and *fps_base* are not given the current scene is used.
:arg frame: number.
- :type frame: the frame number
+ :type frame: int or float.
:return: the time in seconds.
:rtype: datetime.timedelta
"""
@@ -459,7 +454,7 @@ def time_to_frame(time, fps=None, fps_base=None):
If *fps* and *fps_base* are not given the current scene is used.
:arg time: time in seconds.
- :type time: number or a datetime.timedelta object
+ :type time: number or a ``datetime.timedelta`` object
:return: the frame.
:rtype: float
"""
diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py
index 4ee5e685668..021a8bbb530 100644
--- a/release/scripts/modules/bpy_extras/anim_utils.py
+++ b/release/scripts/modules/bpy_extras/anim_utils.py
@@ -142,6 +142,13 @@ def bake_action(frame_start,
obj_info.append(obj_frame_info(obj))
# -------------------------------------------------------------------------
+ # Clean (store initial data)
+ if do_clean and action is not None:
+ clean_orig_data = {fcu: {p.co[1] for p in fcu.keyframe_points} for fcu in action.fcurves}
+ else:
+ clean_orig_data = {}
+
+ # -------------------------------------------------------------------------
# Create action
# in case animation data hasn't been created
@@ -230,12 +237,19 @@ def bake_action(frame_start,
if do_clean:
for fcu in action.fcurves:
+ fcu_orig_data = clean_orig_data.get(fcu, set())
+
keyframe_points = fcu.keyframe_points
i = 1
- while i < len(fcu.keyframe_points) - 1:
+ while i < len(keyframe_points) - 1:
+ val = keyframe_points[i].co[1]
+
+ if val in fcu_orig_data:
+ i += 1
+ continue
+
val_prev = keyframe_points[i - 1].co[1]
val_next = keyframe_points[i + 1].co[1]
- val = keyframe_points[i].co[1]
if abs(val - val_prev) + abs(val - val_next) < 0.0001:
keyframe_points.remove(keyframe_points[i])
diff --git a/release/scripts/modules/bpy_extras/image_utils.py b/release/scripts/modules/bpy_extras/image_utils.py
index ff6d23badb6..ad774cd1bda 100644
--- a/release/scripts/modules/bpy_extras/image_utils.py
+++ b/release/scripts/modules/bpy_extras/image_utils.py
@@ -32,6 +32,8 @@ def load_image(imagepath,
convert_callback=None,
verbose=False,
relpath=None,
+ check_existing=False,
+ force_reload=False,
):
"""
Return an image from the file path with options to search multiple paths
@@ -60,6 +62,12 @@ def load_image(imagepath,
:type convert_callback: function
:arg relpath: If not None, make the file relative to this path.
:type relpath: None or string
+ :arg check_existing: If true, returns already loaded image datablock if possible
+ (based on file path).
+ :type check_existing: bool
+ :arg force_reload: If true, force reloading of image (only useful when `check_existing`
+ is also enabled).
+ :type force_reload: bool
:return: an image or None
:rtype: :class:`bpy.types.Image`
"""
@@ -86,7 +94,7 @@ def load_image(imagepath,
path = convert_callback(path)
try:
- image = bpy.data.images.load(path)
+ image = bpy.data.images.load(path, check_existing)
except RuntimeError:
image = None
@@ -102,6 +110,8 @@ def load_image(imagepath,
image = _image_load_placeholder(path)
if image:
+ if force_reload:
+ image.reload()
if relpath is not None:
# make relative
from bpy.path import relpath as relpath_fn
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 78fb6aa8fa2..c2c306e5145 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -33,6 +33,7 @@ import bpy
from bpy.props import (
BoolProperty,
+ BoolVectorProperty,
FloatVectorProperty,
)
@@ -136,16 +137,22 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
if context.space_data and context.space_data.type == 'VIEW_3D':
v3d = context.space_data
- if use_active_layer:
- if v3d and v3d.local_view:
- base.layers_from_view(context.space_data)
- base.layers[scene.active_layer] = True
- else:
- base.layers = [True if i == scene.active_layer
- else False for i in range(len(scene.layers))]
+ if operator is not None and any(operator.layers):
+ base.layers = operator.layers
else:
- if v3d:
- base.layers_from_view(context.space_data)
+ if use_active_layer:
+ if v3d and v3d.local_view:
+ base.layers_from_view(context.space_data)
+ base.layers[scene.active_layer] = True
+ else:
+ base.layers = [True if i == scene.active_layer
+ else False for i in range(len(scene.layers))]
+ else:
+ if v3d:
+ base.layers_from_view(context.space_data)
+
+ if operator is not None:
+ operator.layers = base.layers
obj_new.matrix_world = add_object_align_init(context, operator)
@@ -209,6 +216,12 @@ class AddObjectHelper:
name="Rotation",
subtype='EULER',
)
+ layers = BoolVectorProperty(
+ name="Layers",
+ size=20,
+ subtype='LAYER',
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
@classmethod
def poll(self, context):
diff --git a/release/scripts/modules/nodeitems_utils.py b/release/scripts/modules/nodeitems_utils.py
index 1cc9afc78cc..be6f031217c 100644
--- a/release/scripts/modules/nodeitems_utils.py
+++ b/release/scripts/modules/nodeitems_utils.py
@@ -85,6 +85,7 @@ class NodeItemCustom:
_node_categories = {}
+
def register_node_categories(identifier, cat_list):
if identifier in _node_categories:
raise KeyError("Node categories list '%s' already registered" % identifier)
@@ -167,6 +168,7 @@ def unregister_node_categories(identifier=None):
unregister_node_cat_types(cat_types)
_node_categories.clear()
+
def draw_node_categories_menu(self, context):
for cats in _node_categories.values():
cats[1](self, context)
diff --git a/release/scripts/modules/progress_report.py b/release/scripts/modules/progress_report.py
index 0d1f4f2bef8..fc77a3e998e 100644
--- a/release/scripts/modules/progress_report.py
+++ b/release/scripts/modules/progress_report.py
@@ -20,6 +20,7 @@
import time
+
class ProgressReport:
"""
A basic 'progress report' using either simple prints in console, or WindowManager's 'progress' API.
@@ -98,7 +99,7 @@ class ProgressReport:
def enter_substeps(self, nbr, msg=""):
if msg:
self.update(msg)
- self.steps.append(self.steps[-1] / nbr)
+ self.steps.append(self.steps[-1] / max(nbr, 1))
self.curr_step.append(0)
self.start_time.append(time.time())
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 44722fa7162..195b5767189 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -39,6 +39,11 @@ def rna_idprop_ui_del(item):
pass
+def rna_idprop_ui_prop_update(item, prop):
+ prop_rna = item.path_resolve("[\"%s\"]" % prop.replace("\"", "\\\""), False)
+ prop_rna.update()
+
+
def rna_idprop_ui_prop_get(item, prop, create=True):
rna_ui = rna_idprop_ui_get(item, create)
diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py
index 1b63d1d9d8d..c79865d2fca 100644
--- a/release/scripts/modules/sys_info.py
+++ b/release/scripts/modules/sys_info.py
@@ -26,29 +26,9 @@ import bgl
import sys
-def cutPoint(text, length):
- """Returns position of the last space found before 'length' chars"""
- l = length
- c = text[l]
- while c != ' ':
- l -= 1
- if l == 0:
- return length # no space found
- c = text[l]
- return l
-
-
-def textWrap(text, length=70):
- lines = []
- while len(text) > 70:
- cpt = cutPoint(text, length)
- line, text = text[:cpt], text[cpt + 1:]
- lines.append(line)
- lines.append(text)
- return lines
-
-
def write_sysinfo(op):
+ import textwrap
+
output_filename = "system-info.txt"
output = bpy.data.texts.get(output_filename)
@@ -57,49 +37,56 @@ def write_sysinfo(op):
else:
output = bpy.data.texts.new(name=output_filename)
+ # pretty repr
+ def prepr(v):
+ r = repr(v)
+ vt = type(v)
+ if vt is bytes:
+ r = r[2:-1]
+ elif vt is list or vt is tuple:
+ r = r[1:-1]
+ return r
+
+
header = "= Blender %s System Information =\n" % bpy.app.version_string
- lilies = "%s\n\n" % (len(header) * "=")
- firstlilies = "%s\n" % (len(header) * "=")
- output.write(firstlilies)
+ lilies = "%s\n\n" % ((len(header) - 1) * "=")
+ output.write(lilies[:-1])
output.write(header)
output.write(lilies)
+ def title(text):
+ return "\n%s:\n%s" % (text, lilies)
+
# build info
- output.write("\nBlender:\n")
- output.write(lilies)
- if bpy.app.build_branch and bpy.app.build_branch != "Unknown":
- output.write("version %s, branch %r, commit date %r %r, hash %r, %r\n" %
- (bpy.app.version_string,
- bpy.app.build_branch,
- bpy.app.build_commit_date,
- bpy.app.build_commit_time,
- bpy.app.build_hash,
- bpy.app.build_type))
- else:
- output.write("version %s, revision %r. %r\n" %
- (bpy.app.version_string,
- bpy.app.build_change,
- bpy.app.build_type))
-
- output.write("build date: %r, %r\n" % (bpy.app.build_date, bpy.app.build_time))
- output.write("platform: %r\n" % (bpy.app.build_platform))
- output.write("binary path: %r\n" % (bpy.app.binary_path))
- output.write("build cflags: %r\n" % (bpy.app.build_cflags))
- output.write("build cxxflags: %r\n" % (bpy.app.build_cxxflags))
- output.write("build linkflags: %r\n" % (bpy.app.build_linkflags))
- output.write("build system: %r\n" % (bpy.app.build_system))
+ output.write(title("Blender"))
+ output.write("version: %s, branch: %s, commit date: %s %s, hash: %s, type: %s\n" %
+ (bpy.app.version_string,
+ prepr(bpy.app.build_branch),
+ prepr(bpy.app.build_commit_date),
+ prepr(bpy.app.build_commit_time),
+ prepr(bpy.app.build_hash),
+ prepr(bpy.app.build_type),
+ ))
+
+ output.write("build date: %s, %s\n" % (prepr(bpy.app.build_date), prepr(bpy.app.build_time)))
+ output.write("platform: %s\n" % prepr(bpy.app.build_platform))
+ output.write("binary path: %s\n" % prepr(bpy.app.binary_path))
+ output.write("build cflags: %s\n" % prepr(bpy.app.build_cflags))
+ output.write("build cxxflags: %s\n" % prepr(bpy.app.build_cxxflags))
+ output.write("build linkflags: %s\n" % prepr(bpy.app.build_linkflags))
+ output.write("build system: %s\n" % prepr(bpy.app.build_system))
# python info
- output.write("\nPython:\n")
- output.write(lilies)
+ output.write(title("Python"))
output.write("version: %s\n" % (sys.version))
output.write("paths:\n")
for p in sys.path:
- output.write("\t%r\n" % (p))
+ output.write("\t%r\n" % p)
- output.write("\nDirectories:\n")
- output.write(lilies)
- output.write("scripts: %r\n" % (bpy.utils.script_paths()))
+ output.write(title("Directories"))
+ output.write("scripts:\n")
+ for p in bpy.utils.script_paths():
+ output.write("\t%r\n" % p)
output.write("user scripts: %r\n" % (bpy.utils.script_path_user()))
output.write("pref scripts: %r\n" % (bpy.utils.script_path_pref()))
output.write("datafiles: %r\n" % (bpy.utils.user_resource('DATAFILES')))
@@ -108,19 +95,17 @@ def write_sysinfo(op):
output.write("autosave: %r\n" % (bpy.utils.user_resource('AUTOSAVE')))
output.write("tempdir: %r\n" % (bpy.app.tempdir))
- output.write("\nFFmpeg:\n")
- output.write(lilies)
+ output.write(title("FFmpeg"))
ffmpeg = bpy.app.ffmpeg
if ffmpeg.supported:
for lib in ("avcodec", "avdevice", "avformat", "avutil", "swscale"):
- output.write("%r:%r%r\n" % (lib, " " * (10 - len(lib)),
+ output.write("%s:%s%r\n" % (lib, " " * (10 - len(lib)),
getattr(ffmpeg, lib + "_version_string")))
else:
output.write("Blender was built without FFmpeg support\n")
if bpy.app.build_options.sdl:
- output.write("\nSDL\n")
- output.write(lilies)
+ output.write(title("SDL"))
output.write("Version: %s\n" % bpy.app.sdl.version_string)
output.write("Loading method: ")
if bpy.app.build_options.sdl_dynload:
@@ -130,8 +115,7 @@ def write_sysinfo(op):
if not bpy.app.sdl.available:
output.write("WARNING: Blender could not load SDL library\n")
- output.write("\nOther Libraries:\n")
- output.write(lilies)
+ output.write(title("Other Libraries"))
ocio = bpy.app.ocio
output.write("OpenColorIO: ")
if ocio.supported:
@@ -166,8 +150,7 @@ def write_sysinfo(op):
if bpy.app.background:
output.write("\nOpenGL: missing, background mode\n")
else:
- output.write("\nOpenGL\n")
- output.write(lilies)
+ output.write(title("OpenGL"))
version = bgl.glGetString(bgl.GL_RENDERER)
output.write("renderer:\t%r\n" % version)
output.write("vendor:\t\t%r\n" % (bgl.glGetString(bgl.GL_VENDOR)))
@@ -175,12 +158,11 @@ def write_sysinfo(op):
output.write("extensions:\n")
glext = bgl.glGetString(bgl.GL_EXTENSIONS)
- glext = textWrap(glext, 70)
+ glext = textwrap.wrap(glext, 70)
for l in glext:
- output.write("\t\t%r\n" % (l))
+ output.write("\t%s\n" % l)
- output.write("\nImplementation Dependent OpenGL Limits:\n")
- output.write(lilies)
+ output.write(title("Implementation Dependent OpenGL Limits"))
limit = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGetIntegerv(bgl.GL_MAX_TEXTURE_UNITS, limit)
output.write("Maximum Fixed Function Texture Units:\t%d\n" % limit[0])
@@ -204,8 +186,7 @@ def write_sysinfo(op):
if bpy.app.build_options.cycles:
import cycles
- output.write("\nCycles\n")
- output.write(lilies)
+ output.write(title("Cycles"))
output.write(cycles.engine.system_info())
output.current_line_index = 0
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py
index 4047505652f..35c7a55b6da 100644
--- a/release/scripts/startup/bl_operators/__init__.py
+++ b/release/scripts/startup/bl_operators/__init__.py
@@ -28,6 +28,7 @@ _modules = [
"anim",
"clip",
"console",
+ "file",
"image",
"mask",
"mesh",
diff --git a/release/scripts/startup/bl_operators/file.py b/release/scripts/startup/bl_operators/file.py
new file mode 100644
index 00000000000..efcc7d5c65e
--- /dev/null
+++ b/release/scripts/startup/bl_operators/file.py
@@ -0,0 +1,244 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+from bpy.types import Operator
+from bpy.props import (
+ StringProperty,
+ BoolProperty,
+ CollectionProperty,
+ )
+
+# ########## Datablock previews... ##########
+
+
+class WM_OT_previews_batch_generate(Operator):
+ """Generate selected .blend file's previews"""
+ bl_idname = "wm.previews_batch_generate"
+ bl_label = "Batch-Generate Previews"
+ bl_options = {'REGISTER'}
+
+ # -----------
+ # File props.
+ files = CollectionProperty(
+ type=bpy.types.OperatorFileListElement,
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
+
+ directory = StringProperty(
+ maxlen=1024,
+ subtype='FILE_PATH',
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
+
+ # Show only images/videos, and directories!
+ filter_blender = BoolProperty(
+ default=True,
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
+ filter_folder = BoolProperty(
+ default=True,
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
+
+ # -----------
+ # Own props.
+ use_scenes = BoolProperty(
+ default=True,
+ name="Scenes",
+ description="Generate scenes' previews",
+ )
+ use_groups = BoolProperty(
+ default=True,
+ name="Groups",
+ description="Generate groups' previews",
+ )
+ use_objects = BoolProperty(
+ default=True,
+ name="Objects",
+ description="Generate objects' previews",
+ )
+ use_intern_data = BoolProperty(
+ default=True,
+ name="Mat/Tex/...",
+ description="Generate 'internal' previews (materials, textures, images, etc.)",
+ )
+
+ use_trusted = BoolProperty(
+ default=False,
+ name="Trusted Blend Files",
+ description="Enable python evaluation for selected files",
+ )
+
+ def invoke(self, context, event):
+ context.window_manager.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
+ def execute(self, context):
+ if "subprocess" in locals():
+ import imp
+ imp.reload(preview_render)
+ else:
+ import os
+ import subprocess
+ from bl_previews_utils import bl_previews_render as preview_render
+
+ context.window_manager.progress_begin(0, len(self.files))
+ context.window_manager.progress_update(0)
+ for i, fn in enumerate(self.files):
+ blen_path = os.path.join(self.directory, fn.name)
+ cmd = [
+ bpy.app.binary_path,
+ "--background",
+ "--factory-startup",
+ "-noaudio",
+ ]
+ if self.use_trusted:
+ cmd.append("--enable-autoexec")
+ cmd.extend([
+ blen_path,
+ "--python",
+ os.path.join(os.path.dirname(preview_render.__file__), "bl_previews_render.py"),
+ "--",
+ ])
+ if not self.use_scenes:
+ cmd.append('--no_scenes')
+ if not self.use_groups:
+ cmd.append('--no_groups')
+ if not self.use_objects:
+ cmd.append('--no_objects')
+ if not self.use_intern_data:
+ cmd.append('--no_data_intern')
+ if subprocess.call(cmd):
+ self.report({'ERROR'}, "Previews generation process failed for file '%s'!" % blen_path)
+ context.window_manager.progress_end()
+ return {'CANCELLED'}
+ context.window_manager.progress_update(i + 1)
+ context.window_manager.progress_end()
+
+ return {'FINISHED'}
+
+
+class WM_OT_previews_batch_clear(Operator):
+ """Clear selected .blend file's previews"""
+ bl_idname = "wm.previews_batch_clear"
+ bl_label = "Batch-Clear Previews"
+ bl_options = {'REGISTER'}
+
+ # -----------
+ # File props.
+ files = CollectionProperty(
+ type=bpy.types.OperatorFileListElement,
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
+
+ directory = StringProperty(
+ maxlen=1024,
+ subtype='FILE_PATH',
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
+
+ # Show only images/videos, and directories!
+ filter_blender = BoolProperty(
+ default=True,
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
+ filter_folder = BoolProperty(
+ default=True,
+ options={'HIDDEN', 'SKIP_SAVE'},
+ )
+
+ # -----------
+ # Own props.
+ use_scenes = BoolProperty(
+ default=True,
+ name="Scenes",
+ description="Clear scenes' previews",
+ )
+ use_groups = BoolProperty(default=True,
+ name="Groups",
+ description="Clear groups' previews",
+ )
+ use_objects = BoolProperty(
+ default=True,
+ name="Objects",
+ description="Clear objects' previews",
+ )
+ use_intern_data = BoolProperty(
+ default=True,
+ name="Mat/Tex/...",
+ description="Clear 'internal' previews (materials, textures, images, etc.)",
+ )
+
+ use_trusted = BoolProperty(
+ default=False,
+ name="Trusted Blend Files",
+ description="Enable python evaluation for selected files",
+ )
+
+ def invoke(self, context, event):
+ context.window_manager.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
+ def execute(self, context):
+ if "subprocess" in locals():
+ import imp
+ imp.reload(preview_render)
+ else:
+ import os
+ import subprocess
+ from bl_previews_utils import bl_previews_render as preview_render
+
+ context.window_manager.progress_begin(0, len(self.files))
+ context.window_manager.progress_update(0)
+ for i, fn in enumerate(self.files):
+ blen_path = os.path.join(self.directory, fn.name)
+ cmd = [
+ bpy.app.binary_path,
+ "--background",
+ "--factory-startup",
+ "-noaudio",
+ ]
+ if self.use_trusted:
+ cmd.append("--enable-autoexec")
+ cmd.extend([
+ blen_path,
+ "--python",
+ os.path.join(os.path.dirname(preview_render.__file__), "bl_previews_render.py"),
+ "--",
+ "--clear",
+ ])
+ if not self.use_scenes:
+ cmd.append('--no_scenes')
+ if not self.use_groups:
+ cmd.append('--no_groups')
+ if not self.use_objects:
+ cmd.append('--no_objects')
+ if not self.use_intern_data:
+ cmd.append('--no_data_intern')
+ if subprocess.call(cmd):
+ self.report({'ERROR'}, "Previews clear process failed for file '%s'!" % blen_path)
+ context.window_manager.progress_end()
+ return {'CANCELLED'}
+ context.window_manager.progress_update(i + 1)
+ context.window_manager.progress_end()
+
+ return {'FINISHED'}
+
diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index 3d54b133a76..d6aeab5c02b 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -220,7 +220,7 @@ class NODE_OT_add_search(NodeAddOperator, Operator):
self.create_node(context, item.nodetype)
if self.use_transform:
- bpy.ops.transform.translate('INVOKE_DEFAULT', remove_on_cancel=True)
+ bpy.ops.node.translate_attach_remove_on_cancel('INVOKE_DEFAULT')
return {'FINISHED'}
else:
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index edf60aa40e7..c228e33965f 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -1132,7 +1132,11 @@ class WM_OT_properties_edit(Operator):
)
def execute(self, context):
- from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear
+ from rna_prop_ui import (
+ rna_idprop_ui_prop_get,
+ rna_idprop_ui_prop_clear,
+ rna_idprop_ui_prop_update,
+ )
data_path = self.data_path
value = self.value
@@ -1164,6 +1168,9 @@ class WM_OT_properties_edit(Operator):
exec_str = "item[%r] = %s" % (prop, repr(value_eval))
# print(exec_str)
exec(exec_str)
+
+ rna_idprop_ui_prop_update(item, prop)
+
self._last_prop[:] = [prop]
prop_type = type(item[prop])
@@ -1245,7 +1252,10 @@ class WM_OT_properties_add(Operator):
data_path = rna_path
def execute(self, context):
- from rna_prop_ui import rna_idprop_ui_prop_get
+ from rna_prop_ui import (
+ rna_idprop_ui_prop_get,
+ rna_idprop_ui_prop_update,
+ )
data_path = self.data_path
item = eval("context.%s" % data_path)
@@ -1263,6 +1273,7 @@ class WM_OT_properties_add(Operator):
prop = unique_name(item.keys())
item[prop] = 1.0
+ rna_idprop_ui_prop_update(item, prop)
# not essential, but without this we get [#31661]
prop_ui = rna_idprop_ui_prop_get(item, prop)
@@ -1298,10 +1309,14 @@ class WM_OT_properties_remove(Operator):
property = rna_property
def execute(self, context):
- from rna_prop_ui import rna_idprop_ui_prop_clear
+ from rna_prop_ui import (
+ rna_idprop_ui_prop_clear,
+ rna_idprop_ui_prop_update,
+ )
data_path = self.data_path
item = eval("context.%s" % data_path)
prop = self.property
+ rna_idprop_ui_prop_update(item, prop)
del item[prop]
rna_idprop_ui_prop_clear(item, prop)
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index 84e06d4c7fc..3c9e2eb8f8b 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -186,7 +186,6 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
# column of operators for active pose
# - goes beside list
col = row.column(align=True)
- col.active = (poselib.library is None)
# invoke should still be used for 'add', as it is needed to allow
# add/replace options to be used properly
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index a14e34580c5..2c7f18b3dfe 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -229,6 +229,8 @@ class BONE_PT_display(BoneButtonsPanel, Panel):
col.label(text="Custom Shape:")
col.prop(pchan, "custom_shape", text="")
if pchan.custom_shape:
+ col.prop(pchan, "use_custom_shape_bone_size", text="Bone Size")
+ col.prop(pchan, "custom_shape_scale", text="Scale")
col.prop_search(pchan, "custom_shape_transform", ob.pose, "bones", text="At")
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index eb8ffa1fb60..f83dea996e6 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -286,7 +286,7 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel):
sub.prop(act_spline, "order_v", text="V")
sub.prop(act_spline, "resolution_v", text="V")
- if not is_surf:
+ if act_spline.type == 'BEZIER':
col = layout.column()
col.label(text="Interpolation:")
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 549c75d6fda..de8617ecc52 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -874,6 +874,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.label(text="Options:")
col.prop(md, "use_subsurf_uv")
col.prop(md, "show_only_control_edges")
+ if hasattr(md, "use_opensubdiv"):
+ col.prop(md, "use_opensubdiv")
def SURFACE(self, layout, ob, md):
layout.label(text="Settings are inside the Physics tab")
diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py
index f58a698d194..e0620447185 100644
--- a/release/scripts/startup/bl_ui/properties_freestyle.py
+++ b/release/scripts/startup/bl_ui/properties_freestyle.py
@@ -381,7 +381,6 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
message = "Enable Face Smoothness to use this modifier"
self.draw_modifier_box_error(col.box(), modifier, message)
-
def draw_alpha_modifier(self, context, modifier):
layout = self.layout
@@ -496,7 +495,6 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
row.prop(modifier, "angle_min")
row.prop(modifier, "angle_max")
-
elif modifier.type == 'CURVATURE_3D':
self.draw_modifier_curve_common(box, modifier, False, False)
row = box.row(align=True)
@@ -510,7 +508,6 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
message = "Enable Face Smoothness to use this modifier"
self.draw_modifier_box_error(col.box(), modifier, message)
-
def draw_geometry_modifier(self, context, modifier):
layout = self.layout
@@ -611,7 +608,6 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
elif modifier.type == 'SIMPLIFICATION':
box.prop(modifier, "tolerance")
-
def draw(self, context):
layout = self.layout
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index fa57bf2115f..ed1253ea3bf 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -55,6 +55,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
layout.prop(game, "step_height", slider=True)
layout.prop(game, "jump_speed")
layout.prop(game, "fall_speed")
+ layout.prop(game, "jump_max")
elif physics_type in {'DYNAMIC', 'RIGID_BODY'}:
split = layout.split()
@@ -247,7 +248,7 @@ class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
game = context.object.game
rd = context.scene.render
return (rd.engine in cls.COMPAT_ENGINES) \
- and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'SOFT_BODY'})
+ and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'SOFT_BODY', 'CHARACTER', 'NO_COLLISION'})
def draw_header(self, context):
game = context.active_object.game
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index e86fc79e343..91a986d8e50 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -303,6 +303,8 @@ class GPENCIL_PIE_tools_more(Menu):
pie.operator("wm.call_menu_pie", text="Back to Main Palette...").name = "GPENCIL_PIE_tool_palette"
+###############################
+
class GPENCIL_UL_layer(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.GPencilLayer)
@@ -354,7 +356,9 @@ class GreasePencilDataPanel:
layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink")
# Grease Pencil data...
- if gpd:
+ if (gpd is None) or (not gpd.layers):
+ layout.operator("gpencil.layer_add", text="New Layer")
+ else:
self.draw_layers(context, layout, gpd)
def draw_layers(self, context, layout, gpd):
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 88b7e0802ce..1f1802aa373 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -459,8 +459,12 @@ class RENDER_PT_encoding(RenderButtonsPanel, Panel):
split = layout.split()
split.prop(rd.ffmpeg, "format")
- if ffmpeg.format in {'AVI', 'QUICKTIME', 'MKV', 'OGG'}:
+ if ffmpeg.format in {'AVI', 'QUICKTIME', 'MKV', 'OGG', 'MPEG4'}:
split.prop(ffmpeg, "codec")
+ if ffmpeg.codec == 'H264':
+ row = layout.row()
+ row.label()
+ row.prop(ffmpeg, "use_lossless_output")
elif rd.ffmpeg.format == 'H264':
split.prop(ffmpeg, "use_lossless_output")
else:
diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
index 8a3e33f1936..9b8bc237db9 100644
--- a/release/scripts/startup/bl_ui/properties_render_layer.py
+++ b/release/scripts/startup/bl_ui/properties_render_layer.py
@@ -187,6 +187,7 @@ class RENDERLAYER_UL_renderviews(UIList):
class RENDERLAYER_PT_views(RenderLayerButtonsPanel, Panel):
bl_label = "Views"
COMPAT_ENGINES = {'BLENDER_RENDER'}
+ bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
rd = context.scene.render
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 7fd9719a6e3..34137c8e9d3 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -153,7 +153,8 @@ class DOPESHEET_HT_header(Header):
row = layout.row(align=True)
row.operator("action.copy", text="", icon='COPYDOWN')
row.operator("action.paste", text="", icon='PASTEDOWN')
- row.operator("action.paste", text="", icon='PASTEFLIPDOWN').flipped = True
+ if st.mode not in ('GPENCIL', 'MASK'):
+ row.operator("action.paste", text="", icon='PASTEFLIPDOWN').flipped = True
class DOPESHEET_MT_editor_menus(Menu):
@@ -338,7 +339,7 @@ class DOPESHEET_MT_key(Menu):
layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode")
layout.separator()
- layout.operator("action.clean")
+ layout.operator("action.clean").channels = False
layout.operator("action.clean", text="Clean Channels").channels = True
layout.operator("action.sample")
@@ -421,7 +422,7 @@ class DOPESHEET_MT_delete(Menu):
layout.separator()
- layout.operator("action.clean")
+ layout.operator("action.clean").channels = False
layout.operator("action.clean", text="Clean Channels").channels = True
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index 0d900a41f25..d7b93dc36f0 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -40,22 +40,23 @@ class FILEBROWSER_HT_header(Header):
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)
+ layout.separator()
layout.operator_context = 'EXEC_DEFAULT'
- row.operator("file.directory_new", icon='NEWFOLDER')
+ layout.operator("file.directory_new", icon='NEWFOLDER', text="")
+ layout.separator()
layout.operator_context = 'INVOKE_DEFAULT'
params = st.params
# can be None when save/reload with a file selector open
if params:
+ is_lib_browser = params.use_library_browsing
+
+ layout.prop(params, "recursion_level", text="")
+
layout.prop(params, "display_type", expand=True, text="")
- if params.display_type == 'FILE_IMGDISPLAY':
- layout.prop(params, "thumbnail_size", text="")
+ layout.prop(params, "display_size", text="")
layout.prop(params, "sort_method", expand=True, text="")
@@ -68,8 +69,8 @@ class FILEBROWSER_HT_header(Header):
row.prop(params, "use_filter_folder", text="")
if params.filter_glob:
- #if st.active_operator and hasattr(st.active_operator, "filter_glob"):
- # row.prop(params, "filter_glob", text="")
+ # if st.active_operator and hasattr(st.active_operator, "filter_glob"):
+ # row.prop(params, "filter_glob", text="")
row.label(params.filter_glob)
else:
row.prop(params, "use_filter_blender", text="")
@@ -81,9 +82,17 @@ class FILEBROWSER_HT_header(Header):
row.prop(params, "use_filter_sound", text="")
row.prop(params, "use_filter_text", text="")
+ if is_lib_browser:
+ row.prop(params, "use_filter_blendid", text="")
+ if params.use_filter_blendid:
+ row.separator()
+ row.prop(params, "filter_id_category", text="")
+
row.separator()
row.prop(params, "filter_search", text="", icon='VIEWZOOM')
+ layout.template_running_jobs()
+
class FILEBROWSER_UL_dir(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
@@ -214,5 +223,29 @@ class FILEBROWSER_PT_recent_folders(Panel):
col.operator("file.reset_recent", icon='X', text="")
+class FILEBROWSER_PT_advanced_filter(Panel):
+ bl_space_type = 'FILE_BROWSER'
+ bl_region_type = 'TOOLS'
+ bl_category = "Filter"
+ bl_label = "Advanced Filter"
+
+ @classmethod
+ def poll(cls, context):
+ # only useful in append/link (library) context currently...
+ return context.space_data.params.use_library_browsing
+
+ def draw(self, context):
+ layout = self.layout
+ space = context.space_data
+ params = space.params
+
+ if params and params.use_library_browsing:
+ layout.prop(params, "use_filter_blendid")
+ if params.use_filter_blendid:
+ layout.separator()
+ col = layout.column()
+ col.prop(params, "filter_id")
+
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index 104fd14797e..82497f11bb1 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -257,7 +257,7 @@ class GRAPH_MT_key(Menu):
layout.operator_menu_enum("graph.easing_type", "type", text="Easing Type")
layout.separator()
- layout.operator("graph.clean")
+ layout.operator("graph.clean").channels = False
layout.operator("graph.clean", text="Clean Channels").channels = True
layout.operator("graph.smooth")
layout.operator("graph.sample")
@@ -293,7 +293,7 @@ class GRAPH_MT_delete(Menu):
layout.separator()
- layout.operator("graph.clean")
+ layout.operator("graph.clean").channels = False
layout.operator("graph.clean", text="Clean Channels").channels = True
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index b3fc643cc41..c3024b25282 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -705,7 +705,7 @@ class IMAGE_PT_tools_transform_uvs(Panel, UVToolsPanel):
col.operator("transform.shear")
-class IMAGE_PT_paint(Panel, BrushButtonsPanel):
+class IMAGE_PT_paint(Panel, ImagePaintPanel):
bl_label = "Paint"
bl_category = "Tools"
@@ -721,6 +721,11 @@ class IMAGE_PT_paint(Panel, BrushButtonsPanel):
if brush:
brush_texpaint_common(self, context, layout, brush, settings)
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ toolsettings = context.tool_settings.image_paint
+ return sima.show_paint
class IMAGE_PT_tools_brush_overlay(BrushButtonsPanel, Panel):
bl_label = "Overlay"
@@ -920,7 +925,7 @@ class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
-class VIEW3D_PT_tools_imagepaint_symmetry(BrushButtonsPanel, Panel):
+class IMAGE_PT_tools_imagepaint_symmetry(BrushButtonsPanel, Panel):
bl_category = "Tools"
bl_context = "imagepaint"
bl_label = "Tiling"
@@ -936,7 +941,7 @@ class VIEW3D_PT_tools_imagepaint_symmetry(BrushButtonsPanel, Panel):
row = col.row(align=True)
row.prop(ipaint, "tile_x", text="X", toggle=True)
row.prop(ipaint, "tile_y", text="Y", toggle=True)
-
+
class IMAGE_PT_tools_brush_appearance(BrushButtonsPanel, Panel):
bl_label = "Appearance"
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 48a1b28289e..d295cc19fb7 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -203,6 +203,12 @@ class INFO_MT_file_previews(Menu):
layout = self.layout
layout.operator("wm.previews_ensure")
+ layout.operator("wm.previews_batch_generate")
+
+ layout.separator()
+
+ layout.operator("wm.previews_clear")
+ layout.operator("wm.previews_batch_clear")
class INFO_MT_game(Menu):
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index a3066cb4ba8..58df86402a6 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -177,8 +177,10 @@ class SEQUENCER_MT_view(Menu):
layout.separator()
if is_sequencer_view:
+ layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("sequencer.view_all", text="View all Sequences")
layout.operator("sequencer.view_selected")
+ layout.operator_context = 'INVOKE_DEFAULT'
if is_preview:
layout.operator_context = 'INVOKE_REGION_PREVIEW'
layout.operator("sequencer.view_all_preview", text="Fit preview in window")
@@ -549,6 +551,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
if strip.input_count > 0:
col = layout.column()
+ col.enabled = False
col.prop(strip, "input_1")
if strip.input_count > 1:
col.prop(strip, "input_2")
@@ -636,8 +639,10 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
col.prop(strip, "text")
col.prop(strip, "font_size")
col.prop(strip, "use_shadow")
- col.prop(strip, "align")
+ col.prop(strip, "align_x")
+ col.prop(strip, "align_y")
col.prop(strip, "location")
+ col.prop(strip, "wrap_width")
layout.operator("sequencer.export_subtitles")
col = layout.column(align=True)
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index c4c4097315c..817c28c6359 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -230,7 +230,7 @@ class TIME_MT_autokey(Menu):
def marker_menu_generic(layout):
- #layout.operator_context = 'EXEC_REGION_WIN'
+ # layout.operator_context = 'EXEC_REGION_WIN'
layout.column()
layout.operator("marker.add", "Add Marker")
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 55a436b6967..e58fe1e0c33 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -493,7 +493,8 @@ class USERPREF_PT_system(Panel):
col.separator()
col.label(text="Sequencer / Clip Editor:")
- col.prop(system, "prefetch_frames")
+ # currently disabled in the code
+ # col.prop(system, "prefetch_frames")
col.prop(system, "memory_cache_limit")
# 3. Column
@@ -1190,7 +1191,7 @@ class USERPREF_MT_addons_dev_guides(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("wm.url_open", text="API Concepts", icon='URL').url = "http://wiki.blender.org/index.php/Dev:2.5/Py/API/Intro"
+ layout.operator("wm.url_open", text="API Concepts", icon='URL').url = bpy.types.WM_OT_doc_view._prefix + "/info_quickstart.html"
layout.operator("wm.url_open", text="Addon Guidelines", icon='URL').url = "http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons"
layout.operator("wm.url_open", text="How to share your addon", icon='URL').url = "http://wiki.blender.org/index.php/Dev:Py/Sharing"
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index f5db15dae35..7cca831257a 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1999,7 +1999,7 @@ class VIEW3D_MT_pose_group(Menu):
layout.separator()
- #layout.operator_context = 'INVOKE_AREA'
+ # layout.operator_context = 'INVOKE_AREA'
layout.operator("pose.group_unassign")
layout.operator("pose.group_remove")
@@ -3293,7 +3293,7 @@ class VIEW3D_PT_background_image(Panel):
box.template_image(bg, "image", bg.image_user, compact=True)
has_bg = True
- if use_multiview and bg.view_axis in {'CAMERA','ALL'}:
+ if use_multiview and bg.view_axis in {'CAMERA', 'ALL'}:
box.prop(bg.image, "use_multiview")
column = box.column()
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 2294e109f0c..a24dc494c30 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1552,7 +1552,6 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
row.prop(sculpt, "lock_y", text="Y", toggle=True)
row.prop(sculpt, "lock_z", text="Z", toggle=True)
-
layout.label(text="Tiling:")
row = layout.row(align=True)
@@ -1562,6 +1561,7 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
layout.column().prop(sculpt, "tile_offset", text="Tile Offset")
+
class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
bl_category = "Options"
bl_label = "Appearance"