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:
authorAntony Riakiotakis <kalast@gmail.com>2014-09-08 20:15:42 +0400
committerAntony Riakiotakis <kalast@gmail.com>2014-09-08 20:15:42 +0400
commitd9ffc99e66d659ac887d801b9cc071b4c3f9b8ab (patch)
treed88e83b5a9edab115081641d26c811b6aa22296a /release
parent551ebaa3dd758bc1975548c28766bfa3159d3846 (diff)
parentb1490e39dd1017e51984d8a34d226e869bbb25df (diff)
Merge branch 'master' into soc-2014-viewport_fxsoc-2014-viewport_fx
I have resolved some differences, for instance selection code which was more or less a stub, to be the same as master. This will have to be fixed later. Conflicts: CMakeLists.txt intern/ghost/CMakeLists.txt intern/ghost/intern/GHOST_SystemWin32.cpp intern/ghost/intern/GHOST_Window.cpp intern/ghost/intern/GHOST_WindowWin32.cpp intern/ghost/intern/GHOST_WindowX11.cpp source/blender/blenlib/BLI_math_matrix.h source/blender/blenlib/intern/math_matrix.c source/blender/gpu/CMakeLists.txt source/blender/gpu/GPU_select.h source/blender/gpu/intern/gpu_buffers.c source/blender/gpu/intern/gpu_draw.c source/blender/gpu/intern/gpu_extensions.c source/blender/gpu/intern/gpu_select.c source/blender/gpu/shaders/gpu_shader_simple_vert.glsl source/blender/nodes/CMakeLists.txt
Diffstat (limited to 'release')
-rw-r--r--release/darwin/README_codesigning.txt5
-rw-r--r--release/darwin/codesigning_rules_blender.plist14
-rw-r--r--release/darwin/codesigning_rules_player.plist15
-rw-r--r--release/datafiles/blender_icons.svg215
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_bounce.datbin1048 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_ipo_elastic.datbin1048 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_loopsel.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_loopsel.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_nla_pushdown.datbin4120 -> 4120 bytes
-rwxr-xr-xrelease/datafiles/prvicons_update.py11
-rw-r--r--release/scripts/freestyle/modules/freestyle/chainingiterators.py2
-rw-r--r--release/scripts/freestyle/modules/freestyle/functions.py37
-rw-r--r--release/scripts/freestyle/modules/freestyle/predicates.py68
-rw-r--r--release/scripts/freestyle/modules/freestyle/shaders.py64
-rw-r--r--release/scripts/freestyle/modules/freestyle/types.py2
-rw-r--r--release/scripts/freestyle/modules/freestyle/utils.py317
-rw-r--r--release/scripts/freestyle/modules/parameter_editor.py1017
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py4
-rw-r--r--release/scripts/modules/bpy/path.py5
-rw-r--r--release/scripts/modules/bpy/utils.py8
-rw-r--r--release/scripts/modules/bpy_extras/mesh_utils.py1
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py1
-rw-r--r--release/scripts/modules/bpy_types.py9
-rw-r--r--release/scripts/modules/rna_prop_ui.py3
-rw-r--r--release/scripts/modules/sys_info.py26
-rw-r--r--release/scripts/presets/camera/1__colon__2.3_inch.py6
-rw-r--r--release/scripts/presets/camera/1__colon__2.5_inch.py6
-rw-r--r--release/scripts/presets/camera/2__colon__3_inch.py6
-rw-r--r--release/scripts/presets/camera/4__colon__3_inch.py6
-rw-r--r--release/scripts/presets/camera/Arri_Alexa.py6
-rw-r--r--release/scripts/presets/camera/Blackmagic_Cinema_Camera.py6
-rw-r--r--release/scripts/presets/camera/Blackmagic_Pocket_Cinema_Camera.py4
-rw-r--r--release/scripts/presets/camera/Blackmagic_Production_Camera_4K.py4
-rw-r--r--release/scripts/presets/camera/Blender.py6
-rw-r--r--release/scripts/presets/camera/Canon_1100D.py6
-rw-r--r--release/scripts/presets/camera/Canon_APS-C.py6
-rw-r--r--release/scripts/presets/camera/Canon_APS-H.py6
-rw-r--r--release/scripts/presets/camera/Canon_C300.py6
-rw-r--r--release/scripts/presets/camera/Full_Frame_35mm_Camera.py6
-rw-r--r--release/scripts/presets/camera/GoPro_Hero3_Black.py8
-rw-r--r--release/scripts/presets/camera/GoPro_Hero3_Silver.py8
-rw-r--r--release/scripts/presets/camera/GoPro_Hero3_White.py8
-rw-r--r--release/scripts/presets/camera/Nexus_5.py8
-rw-r--r--release/scripts/presets/camera/Nikon_D3100.py6
-rw-r--r--release/scripts/presets/camera/Nikon_DX.py6
-rw-r--r--release/scripts/presets/camera/Panasonic_AG-HVX200.py6
-rw-r--r--release/scripts/presets/camera/Panasonic_LX2.py6
-rw-r--r--release/scripts/presets/camera/Red_Epic.py6
-rw-r--r--release/scripts/presets/camera/Red_One_2K.py6
-rw-r--r--release/scripts/presets/camera/Red_One_3K.py6
-rw-r--r--release/scripts/presets/camera/Red_One_4K.py6
-rw-r--r--release/scripts/presets/camera/Samsung_Galaxy_S3.py8
-rw-r--r--release/scripts/presets/camera/Samsung_Galaxy_S4.py8
-rw-r--r--release/scripts/presets/camera/Sony_A55.py6
-rw-r--r--release/scripts/presets/camera/Sony_EX1.py6
-rw-r--r--release/scripts/presets/camera/Sony_F65.py6
-rw-r--r--release/scripts/presets/camera/Super_16_Film.py6
-rw-r--r--release/scripts/presets/camera/Super_35_Film.py6
-rw-r--r--release/scripts/presets/camera/iPhone_4.py8
-rw-r--r--release/scripts/presets/camera/iPhone_4S.py8
-rw-r--r--release/scripts/presets/camera/iPhone_5.py8
-rw-r--r--release/scripts/presets/cycles/integrator/direct_light.py4
-rw-r--r--release/scripts/presets/cycles/integrator/full_global_illumination.py4
-rw-r--r--release/scripts/presets/cycles/integrator/limited_global_illumination.py4
-rw-r--r--release/scripts/presets/interface_theme/back_to_black.xml117
-rw-r--r--release/scripts/presets/interface_theme/blender_24x.xml85
-rw-r--r--release/scripts/presets/interface_theme/elsyiun.xml85
-rw-r--r--release/scripts/presets/interface_theme/hexagon.xml85
-rw-r--r--release/scripts/presets/interface_theme/ubuntu_ambiance.xml85
-rw-r--r--release/scripts/presets/keyconfig/3dsmax.py38
-rw-r--r--release/scripts/presets/keyconfig/maya.py19
-rw-r--r--release/scripts/presets/sunsky/classic.py26
-rw-r--r--release/scripts/presets/sunsky/desert.py26
-rw-r--r--release/scripts/presets/sunsky/mountain.py26
-rw-r--r--release/scripts/presets/tracking_camera/Blackmagic_Pocket_Cinema_Camera.py9
-rw-r--r--release/scripts/presets/tracking_camera/Blackmagic_Production_Camera_4K.py9
-rw-r--r--release/scripts/startup/bl_operators/object.py17
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py229
-rw-r--r--release/scripts/startup/bl_operators/presets.py4
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py4
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py2
-rw-r--r--release/scripts/startup/bl_operators/vertexpaint_dirt.py2
-rw-r--r--release/scripts/startup/bl_operators/view3d.py7
-rw-r--r--release/scripts/startup/bl_operators/wm.py79
-rw-r--r--release/scripts/startup/bl_ui/properties_constraint.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_data_empty.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_freestyle.py19
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py28
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py155
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py1
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py2
-rw-r--r--release/scripts/startup/bl_ui/space_image.py134
-rw-r--r--release/scripts/startup/bl_ui/space_info.py10
-rw-r--r--release/scripts/startup/bl_ui/space_node.py10
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py34
-rw-r--r--release/scripts/startup/bl_ui/space_time.py5
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py16
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py10
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py288
-rw-r--r--release/scripts/startup/nodeitems_builtins.py10
-rw-r--r--release/scripts/templates_osl/fresnel_conductive.osl38
-rw-r--r--release/scripts/templates_py/ui_pie_menu.py32
-rw-r--r--release/text/readme.html10
106 files changed, 2315 insertions, 1526 deletions
diff --git a/release/darwin/README_codesigning.txt b/release/darwin/README_codesigning.txt
index d2ead00da8a..3724ad1b0ac 100644
--- a/release/darwin/README_codesigning.txt
+++ b/release/darwin/README_codesigning.txt
@@ -1,11 +1,12 @@
Tutorial for codesigning Blender releases on OSX ( atm. i do manually when needed ):
+Updated as by august 01.2014 - removed deprecated rules and not recommended deep codesigning
1. You need to obtain the certificates for blender foundation, they can bw pulled at Apple developer account for BF
2. Run the following commands from terminal:
-codesign -s <IDENTITY> <path_to_blender.app> --resource-rules <path_to_blender_source>/release/darwin/codesigning_rules_blender.plist --deep
+codesign -s <IDENTITY> <path_to_blender.app>
-codesign -s <IDENTITY> <path_to_blenderplayer.app> --resource-rules <path_to_blender_source>/release/darwin/codesigning_rules_player.plist --deep
+codesign -s <IDENTITY> <path_to_blenderplayer.app>
3. Checking:
diff --git a/release/darwin/codesigning_rules_blender.plist b/release/darwin/codesigning_rules_blender.plist
deleted file mode 100644
index 5e6198e8ce7..00000000000
--- a/release/darwin/codesigning_rules_blender.plist
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>rules</key>
- <dict>
- <!-- Exclude datafiles, python and scripts -->
- <key>^MacOS/2.71</key>
- <false/>
- <key>^Resources/</key>
- <true/>
- </dict>
-</dict>
-</plist>
diff --git a/release/darwin/codesigning_rules_player.plist b/release/darwin/codesigning_rules_player.plist
deleted file mode 100644
index acbdab20db9..00000000000
--- a/release/darwin/codesigning_rules_player.plist
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>rules</key>
- <dict>
- <!-- Exclude datafiles, python and scripts -->
- <key>^MacOS/2.71</key>
- <false/>
- <!-- Exclude Resources for placing game.blend and own icons -->
- <key>^Resources/</key>
- <false/>
- </dict>
-</dict>
-</plist>
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
index 7557b81c804..4a1e2cd1d9a 100644
--- a/release/datafiles/blender_icons.svg
+++ b/release/datafiles/blender_icons.svg
@@ -14,7 +14,7 @@
height="640"
id="svg2"
sodipodi:version="0.32"
- inkscape:version="0.48.4 r"
+ inkscape:version="0.48.5 r10040"
version="1.0"
sodipodi:docname="blender_icons.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
@@ -27,6 +27,17 @@
<defs
id="defs4">
<linearGradient
+ id="linearGradient17265">
+ <stop
+ style="stop-color:#ffb769;stop-opacity:1;"
+ offset="0"
+ id="stop17267" />
+ <stop
+ style="stop-color:#ffeeaa;stop-opacity:0;"
+ offset="1"
+ id="stop17269" />
+ </linearGradient>
+ <linearGradient
id="linearGradient17073">
<stop
style="stop-color:#2561b7;stop-opacity:1;"
@@ -28232,6 +28243,79 @@
id="linearGradient16728"
xlink:href="#linearGradient44939-8-53-7"
inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-0"
+ id="linearGradient36725-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="104.90227"
+ y1="53.227627"
+ x2="117.12428"
+ y2="61.720783" />
+ <linearGradient
+ id="linearGradient319-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-22" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-19" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-0"
+ id="linearGradient36727-5"
+ gradientUnits="userSpaceOnUse"
+ x1="-56.5"
+ y1="340.32199"
+ x2="-56.5"
+ y2="348" />
+ <linearGradient
+ id="linearGradient16404-5">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16406" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16408" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-0"
+ id="linearGradient36729-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.7972867,61.99991,2.2419)"
+ x1="260.67468"
+ y1="108.02418"
+ x2="273.9993"
+ y2="126.37626" />
+ <linearGradient
+ id="linearGradient16411">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop16413" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop16415" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17265"
+ id="radialGradient17275"
+ cx="1130.7738"
+ cy="440.25275"
+ fx="1130.7738"
+ fy="440.25275"
+ r="3.5"
+ gradientTransform="matrix(1.4878857,2.6976762,-1.4698319,0.81067624,95.409128,-2969.0604)"
+ gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
@@ -88543,6 +88627,135 @@
inkscape:connector-curvature="0" />
</g>
</g>
+ <g
+ transform="translate(21,0)"
+ style="display:inline;enable-background:new"
+ id="g106643-9">
+ <g
+ transform="translate(111,-158)"
+ id="g35778-7"
+ style="opacity:0.55;display:inline">
+ <rect
+ y="336"
+ x="-64"
+ height="16"
+ width="16"
+ id="rect35780-2"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g35782-9"
+ transform="translate(1,0)">
+ <g
+ id="g35785-7"
+ transform="translate(-386,446.5)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ id="path35787-2" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path35789-6"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccc" />
+ <g
+ id="g35791-0"
+ transform="translate(179,-179)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path35793-5"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35795-5"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path35797-0"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient36725-1);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ <rect
+ y="342"
+ x="-57"
+ height="7.75"
+ width="1"
+ id="rect35799-0"
+ style="fill:url(#linearGradient36727-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35801-8"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient36729-0);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <rect
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37868-0-4-8-7"
+ width="3.0000007"
+ height="7.25"
+ x="54"
+ y="185" />
+ <g
+ id="g35818-3"
+ style="fill:url(#radialGradient17275);display:inline;fill-opacity:1"
+ transform="translate(-1080.9861,-256)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="fill:url(#radialGradient17275);fill-opacity:1;fill-rule:nonzero;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.86274510000000004;stroke-dasharray:none;stroke-dashoffset:7.40000265000000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 1130.4859,445.25 0,-7.5 6,2.75 0,8 -6,-3.25 z"
+ id="path35820-8"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path35822-7"
+ d="m 1136.4859,448.5 -6,-3.25 0,-7.5"
+ style="fill:url(#radialGradient17275);stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265000000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;fill-opacity:1"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ transform="translate(41.999513,2.6999762e-4)"
+ style="display:inline;enable-background:new"
+ id="g35803-8">
+ <path
+ style="fill:none;stroke:#542b00;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 8.0048608,180.50566 0.036785,0 c 0.8181814,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.6586836,1.49472 -1.476865,1.49472 l -0.036785,0 c -0.8181897,0 -1.4768733,-0.66664 -1.4768733,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.6586836,-1.49473 1.4768733,-1.49473 z"
+ id="path35805-7"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 9.0203881,181.00394 c -0.6673195,0 -1.334639,1e-5 -2.0019585,1e-5 0,0.66706 0,1.33411 0,2.00119 0.6673195,0 1.334639,-1e-5 2.0019585,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ id="path35807-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
</g>
<g
inkscape:groupmode="layer"
diff --git a/release/datafiles/blender_icons16/icon16_ipo_bounce.dat b/release/datafiles/blender_icons16/icon16_ipo_bounce.dat
index bede5e12e57..7a3984a3a13 100644
--- a/release/datafiles/blender_icons16/icon16_ipo_bounce.dat
+++ b/release/datafiles/blender_icons16/icon16_ipo_bounce.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_ipo_elastic.dat b/release/datafiles/blender_icons16/icon16_ipo_elastic.dat
index 5db0f974912..221b0a22236 100644
--- a/release/datafiles/blender_icons16/icon16_ipo_elastic.dat
+++ b/release/datafiles/blender_icons16/icon16_ipo_elastic.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_loopsel.dat b/release/datafiles/blender_icons16/icon16_loopsel.dat
new file mode 100644
index 00000000000..78f9bbe1a6f
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_loopsel.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_loopsel.dat b/release/datafiles/blender_icons32/icon32_loopsel.dat
new file mode 100644
index 00000000000..11d3e9d284e
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_loopsel.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_nla_pushdown.dat b/release/datafiles/blender_icons32/icon32_nla_pushdown.dat
index 83216ac5367..3a0e1c73a52 100644
--- a/release/datafiles/blender_icons32/icon32_nla_pushdown.dat
+++ b/release/datafiles/blender_icons32/icon32_nla_pushdown.dat
Binary files differ
diff --git a/release/datafiles/prvicons_update.py b/release/datafiles/prvicons_update.py
index ecc466aab72..448a43df9ce 100755
--- a/release/datafiles/prvicons_update.py
+++ b/release/datafiles/prvicons_update.py
@@ -2,9 +2,16 @@
# This script updates icons from the SVG file
import os
+import sys
BASEDIR = os.path.abspath(os.path.dirname(__file__)) + os.sep
-cmd = 'inkscape "%sprvicons.svg" --without-gui --export-png="%sprvicons.png"' % (BASEDIR, BASEDIR)
-os.system(cmd)
+inkscape_path = 'inkscape'
+
+if sys.platform == 'darwin':
+ inkscape_app_path = '/Applications/Inkscape.app/Contents/Resources/script'
+ if os.path.exists(inkscape_app_path):
+ inkscape_path = inkscape_app_path
+cmd = inkscape_path + ' "%sprvicons.svg" --without-gui --export-png="%sprvicons.png"' % (BASEDIR, BASEDIR)
+os.system(cmd)
diff --git a/release/scripts/freestyle/modules/freestyle/chainingiterators.py b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
index 5cd0dfeff59..8d144bf17fd 100644
--- a/release/scripts/freestyle/modules/freestyle/chainingiterators.py
+++ b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
@@ -77,7 +77,7 @@ NATURES = (
def nature_in_preceding(nature, index):
- """ Returns True if given nature appears before index, else False """
+ """Returns True if given nature appears before index, else False."""
return any(nature & nat for nat in NATURES[:index])
diff --git a/release/scripts/freestyle/modules/freestyle/functions.py b/release/scripts/freestyle/modules/freestyle/functions.py
index 9e03f8f5dbb..674c1f01864 100644
--- a/release/scripts/freestyle/modules/freestyle/functions.py
+++ b/release/scripts/freestyle/modules/freestyle/functions.py
@@ -19,7 +19,7 @@
"""
Functions operating on vertices (0D elements) and polylines (1D
elements). Also intended to be a collection of examples for predicate
-definition in Python
+definition in Python.
"""
# module members
@@ -91,7 +91,6 @@ from freestyle.utils import integrate
from mathutils import Vector
-
# -- Functions for 0D elements (vertices) -- #
@@ -101,18 +100,17 @@ class CurveMaterialF0D(UnaryFunction0DMaterial):
MaterialF0D does not work with Curves and Strokes. Line color
priority is used to pick one of the two materials at material
boundaries.
+
+ Note: expects instances of CurvePoint to be iterated over
"""
def __call__(self, inter):
- cp = inter.object
- assert(isinstance(cp, CurvePoint))
- fe = cp.first_svertex.get_fedge(cp.second_svertex)
+ fe = inter.object.fedge
assert(fe is not None), "CurveMaterialF0D: fe is None"
if fe.is_smooth:
return fe.material
- elif fe.material_right.priority > fe.material_left.priority:
- return fe.material_right
else:
- return fe.material_left
+ right, left = fe.material_right, fe.material_left
+ return right if (right.priority > left.priority) else left
class pyInverseCurvature2DAngleF0D(UnaryFunction0DDouble):
@@ -130,8 +128,8 @@ class pyCurvilinearLengthF0D(UnaryFunction0DDouble):
class pyDensityAnisotropyF0D(UnaryFunction0DDouble):
- """Estimates the anisotropy of density"""
- def __init__(self,level):
+ """Estimates the anisotropy of density."""
+ def __init__(self, level):
UnaryFunction0DDouble.__init__(self)
self.IsoDensity = ReadCompleteViewMapPixelF0D(level)
self.d0Density = ReadSteerableViewMapPixelF0D(0, level)
@@ -145,13 +143,13 @@ class pyDensityAnisotropyF0D(UnaryFunction0DDouble):
c_1 = self.d1Density(inter)
c_2 = self.d2Density(inter)
c_3 = self.d3Density(inter)
- cMax = max(max(c_0,c_1), max(c_2,c_3))
- cMin = min(min(c_0,c_1), min(c_2,c_3))
- return 0 if (c_iso == 0) else (cMax-cMin) / c_iso
+ cMax = max(max(c_0, c_1), max(c_2, c_3))
+ cMin = min(min(c_0, c_1), min(c_2, c_3))
+ return 0 if (c_iso == 0) else (cMax - cMin) / c_iso
class pyViewMapGradientVectorF0D(UnaryFunction0DVec2f):
- """Returns the gradient vector for a pixel
+ """Returns the gradient vector for a pixel.
:arg level: the level at which to compute the gradient
:type level: int
@@ -163,9 +161,9 @@ class pyViewMapGradientVectorF0D(UnaryFunction0DVec2f):
def __call__(self, iter):
p = iter.object.point_2d
- gx = CF.read_complete_view_map_pixel(self._l, int(p.x+self._step), int(p.y)) - \
+ gx = CF.read_complete_view_map_pixel(self._l, int(p.x + self._step), int(p.y)) - \
CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y))
- gy = CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y+self._step)) - \
+ gy = CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y + self._step)) - \
CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y))
return Vector((gx, gy))
@@ -184,7 +182,6 @@ class pyViewMapGradientNormF0D(UnaryFunction0DDouble):
CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y))
return Vector((gx, gy)).length
-
# -- Functions for 1D elements (curves) -- #
@@ -199,11 +196,11 @@ class pyGetSquareInverseProjectedZF1D(UnaryFunction1DDouble):
def __call__(self, inter):
func = GetProjectedZF1D()
z = func(inter)
- return (1.0 - z*z)
+ return (1.0 - pow(z, 2))
class pyDensityAnisotropyF1D(UnaryFunction1DDouble):
- def __init__(self,level, integrationType=IntegrationType.MEAN, sampling=2.0):
+ def __init__(self, level, integrationType=IntegrationType.MEAN, sampling=2.0):
UnaryFunction1DDouble.__init__(self, integrationType)
self._func = pyDensityAnisotropyF0D(level)
self._integration = integrationType
@@ -215,7 +212,7 @@ class pyDensityAnisotropyF1D(UnaryFunction1DDouble):
class pyViewMapGradientNormF1D(UnaryFunction1DDouble):
- def __init__(self,l, integrationType, sampling=2.0):
+ def __init__(self, l, integrationType, sampling=2.0):
UnaryFunction1DDouble.__init__(self, integrationType)
self._func = pyViewMapGradientNormF0D(l)
self._integration = integrationType
diff --git a/release/scripts/freestyle/modules/freestyle/predicates.py b/release/scripts/freestyle/modules/freestyle/predicates.py
index fede3e3e2da..344b89d869c 100644
--- a/release/scripts/freestyle/modules/freestyle/predicates.py
+++ b/release/scripts/freestyle/modules/freestyle/predicates.py
@@ -46,12 +46,13 @@ from _freestyle import (
# constructs for predicate definition in Python
from freestyle.types import (
BinaryPredicate1D,
+ Id,
IntegrationType,
+ Interface0DIterator,
Nature,
TVertex,
UnaryPredicate0D,
UnaryPredicate1D,
- Id,
)
from freestyle.functions import (
Curvature2DAngleF0D,
@@ -82,11 +83,10 @@ class pyHigherCurvature2DAngleUP0D(UnaryPredicate0D):
def __init__(self, a):
UnaryPredicate0D.__init__(self)
self._a = a
+ self.func = Curvature2DAngleF0D()
def __call__(self, inter):
- func = Curvature2DAngleF0D()
- a = func(inter)
- return (a > self._a)
+ return (self.func(inter) > self._a)
class pyUEqualsUP0D(UnaryPredicate0D):
@@ -102,7 +102,7 @@ class pyUEqualsUP0D(UnaryPredicate0D):
class pyVertexNatureUP0D(UnaryPredicate0D):
- def __init__(self,nature):
+ def __init__(self, nature):
UnaryPredicate0D.__init__(self)
self._nature = nature
@@ -112,9 +112,8 @@ class pyVertexNatureUP0D(UnaryPredicate0D):
class pyBackTVertexUP0D(UnaryPredicate0D):
"""
- Check whether an Interface0DIterator
- references a TVertex and is the one that is
- hidden (inferred from the context)
+ Check whether an Interface0DIterator references a TVertex and is
+ the one that is hidden (inferred from the context).
"""
def __init__(self):
UnaryPredicate0D.__init__(self)
@@ -127,7 +126,7 @@ class pyBackTVertexUP0D(UnaryPredicate0D):
class pyParameterUP0DGoodOne(UnaryPredicate0D):
- def __init__(self,pmin,pmax):
+ def __init__(self, pmin, pmax):
UnaryPredicate0D.__init__(self)
self._m = pmin
self._M = pmax
@@ -138,7 +137,7 @@ class pyParameterUP0DGoodOne(UnaryPredicate0D):
class pyParameterUP0D(UnaryPredicate0D):
- def __init__(self,pmin,pmax):
+ def __init__(self, pmin, pmax):
UnaryPredicate0D.__init__(self)
self._m = pmin
self._M = pmax
@@ -154,13 +153,13 @@ class pyParameterUP0D(UnaryPredicate0D):
# -- Unary predicates for 1D elements (curves) -- #
-
class AndUP1D(UnaryPredicate1D):
def __init__(self, *predicates):
UnaryPredicate1D.__init__(self)
self.predicates = predicates
- if len(self.predicates) < 2:
- raise ValueError("Expected two or more UnaryPredicate1D")
+ # there are cases in which only one predicate is supplied (in the parameter editor)
+ if len(self.predicates) < 1:
+ raise ValueError("Expected one or more UnaryPredicate1D, got ", len(predicates))
def __call__(self, inter):
return all(pred(inter) for pred in self.predicates)
@@ -170,8 +169,9 @@ class OrUP1D(UnaryPredicate1D):
def __init__(self, *predicates):
UnaryPredicate1D.__init__(self)
self.predicates = predicates
- if len(self.predicates) < 2:
- raise ValueError("Expected two or more UnaryPredicate1D")
+ # there are cases in which only one predicate is supplied (in the parameter editor)
+ if len(self.predicates) < 1:
+ raise ValueError("Expected one or more UnaryPredicate1D, got ", len(predicates))
def __call__(self, inter):
return any(pred(inter) for pred in self.predicates)
@@ -230,7 +230,7 @@ class pyHigherLengthUP1D(UnaryPredicate1D):
class pyNatureUP1D(UnaryPredicate1D):
- def __init__(self,nature):
+ def __init__(self, nature):
UnaryPredicate1D.__init__(self)
self._nature = nature
self._getNature = CurveNatureF1D()
@@ -244,12 +244,14 @@ class pyHigherNumberOfTurnsUP1D(UnaryPredicate1D):
UnaryPredicate1D.__init__(self)
self._n = n
self._a = a
+ self.func = Curvature2DAngleF0D()
def __call__(self, inter):
- func = Curvature2DAngleF0D()
- it = inter.vertices_begin()
+ it = Interface0DIterator(inter)
# sum the turns, check against n
- return sum(1 for ve in it if func(it) > self._a) > self._n
+ return sum(1 for _ in it if self.func(it) > self._a) > self._n
+ # interesting fact, the line above is 70% faster than:
+ # return sum(self.func(it) > self._a for _ in it) > self._n
class pyDensityUP1D(UnaryPredicate1D):
@@ -345,7 +347,7 @@ class pyZSmallerUP1D(UnaryPredicate1D):
class pyIsOccludedByUP1D(UnaryPredicate1D):
- def __init__(self,id):
+ def __init__(self, id):
UnaryPredicate1D.__init__(self)
if not isinstance(id, Id):
raise TypeError("pyIsOccludedByUP1D expected freestyle.types.Id, not " + type(id).__name__)
@@ -376,7 +378,7 @@ class pyIsOccludedByUP1D(UnaryPredicate1D):
class pyIsInOccludersListUP1D(UnaryPredicate1D):
- def __init__(self,id):
+ def __init__(self, id):
UnaryPredicate1D.__init__(self)
self._id = id
@@ -409,7 +411,7 @@ class pyIsOccludedByIdListUP1D(UnaryPredicate1D):
class pyShapeIdListUP1D(UnaryPredicate1D):
- def __init__(self,idlist):
+ def __init__(self, idlist):
UnaryPredicate1D.__init__(self)
self._funcs = tuple(ShapeUP1D(_id, 0) for _id in idlist)
@@ -417,7 +419,7 @@ class pyShapeIdListUP1D(UnaryPredicate1D):
return any(func(inter) for func in self._funcs)
-## deprecated
+# DEPRECATED
class pyShapeIdUP1D(UnaryPredicate1D):
def __init__(self, _id):
UnaryPredicate1D.__init__(self)
@@ -429,7 +431,7 @@ class pyShapeIdUP1D(UnaryPredicate1D):
class pyHighDensityAnisotropyUP1D(UnaryPredicate1D):
- def __init__(self,threshold, level, sampling=2.0):
+ def __init__(self, threshold, level, sampling=2.0):
UnaryPredicate1D.__init__(self)
self._l = threshold
self.func = pyDensityAnisotropyF1D(level, IntegrationType.MEAN, sampling)
@@ -439,7 +441,7 @@ class pyHighDensityAnisotropyUP1D(UnaryPredicate1D):
class pyHighViewMapGradientNormUP1D(UnaryPredicate1D):
- def __init__(self,threshold, l, sampling=2.0):
+ def __init__(self, threshold, l, sampling=2.0):
UnaryPredicate1D.__init__(self)
self._threshold = threshold
self._GetGradient = pyViewMapGradientNormF1D(l, IntegrationType.MEAN)
@@ -463,8 +465,9 @@ class pyDensityVariableSigmaUP1D(UnaryPredicate1D):
self._sampling = sampling
def __call__(self, inter):
- sigma = (self._sigmaMax-self._sigmaMin)/(self._lmax-self._lmin)*(self._functor(inter)-self._lmin) + self._sigmaMin
- t = (self._tmax-self._tmin)/(self._lmax-self._lmin)*(self._functor(inter)-self._lmin) + self._tmin
+ result = self._functor(inter) - self._lmin
+ sigma = (self._sigmaMax - self._sigmaMin) / (self._lmax - self._lmin) * result + self._sigmaMin
+ t = (self._tmax - self._tmin) / (self._lmax - self._lmin) * result + self._tmin
sigma = max(sigma, self._sigmaMin)
self._func = DensityF1D(sigma, self._integration, self._sampling)
return (self._func(inter) < t)
@@ -480,13 +483,12 @@ class pyClosedCurveUP1D(UnaryPredicate1D):
# -- Binary predicates for 1D elements (curves) -- #
-
class AndBP1D(BinaryPredicate1D):
def __init__(self, *predicates):
BinaryPredicate1D.__init__(self)
self._predicates = predicates
if len(self.predicates) < 2:
- raise ValueError("Expected two or more BinaryPredicate1D")
+ raise ValueError("Expected two or more BinaryPredicate1D, got ", len(predictates))
def __call__(self, i1, i2):
return all(pred(i1, i2) for pred in self._predicates)
@@ -497,7 +499,7 @@ class OrBP1D(BinaryPredicate1D):
BinaryPredicate1D.__init__(self)
self._predicates = predicates
if len(self.predicates) < 2:
- raise ValueError("Expected two or more BinaryPredicate1D")
+ raise ValueError("Expected two or more BinaryPredicate1D, got ", len(predictates))
def __call__(self, i1, i2):
return any(pred(i1, i2) for pred in self._predicates)
@@ -551,11 +553,11 @@ class pyNatureBP1D(BinaryPredicate1D):
class pyViewMapGradientNormBP1D(BinaryPredicate1D):
- def __init__(self,l, sampling=2.0):
+ def __init__(self, l, sampling=2.0):
BinaryPredicate1D.__init__(self)
self._GetGradient = pyViewMapGradientNormF1D(l, IntegrationType.MEAN)
- def __call__(self, i1,i2):
+ def __call__(self, i1, i2):
return (self._GetGradient(i1) > self._GetGradient(i2))
@@ -565,4 +567,4 @@ class pyShuffleBP1D(BinaryPredicate1D):
random.seed = 1
def __call__(self, inter1, inter2):
- return (random.uniform(0,1) < random.uniform(0,1))
+ return (random.uniform(0, 1) < random.uniform(0, 1))
diff --git a/release/scripts/freestyle/modules/freestyle/shaders.py b/release/scripts/freestyle/modules/freestyle/shaders.py
index 8a9faf26017..502d9b69a97 100644
--- a/release/scripts/freestyle/modules/freestyle/shaders.py
+++ b/release/scripts/freestyle/modules/freestyle/shaders.py
@@ -23,7 +23,7 @@
"""
Stroke shaders used for creation of stylized strokes. Also intended
-to be a collection of examples for shader definition in Python
+to be a collection of examples for shader definition in Python.
"""
# module members
@@ -100,7 +100,7 @@ from random import randint
class pyDepthDiscontinuityThicknessShader(StrokeShader):
"""
Assigns a thickness to the stroke based on the stroke's distance
- to the camera (Z-value)
+ to the camera (Z-value).
"""
def __init__(self, min, max):
StrokeShader.__init__(self)
@@ -118,7 +118,7 @@ class pyDepthDiscontinuityThicknessShader(StrokeShader):
class pyConstantThicknessShader(StrokeShader):
"""
- Assigns a constant thickness along the stroke
+ Assigns a constant thickness along the stroke.
"""
def __init__(self, thickness):
StrokeShader.__init__(self)
@@ -131,7 +131,7 @@ class pyConstantThicknessShader(StrokeShader):
class pyFXSVaryingThicknessWithDensityShader(StrokeShader):
"""
- Assings thickness to a stroke based on the density of the diffuse map
+ Assings thickness to a stroke based on the density of the diffuse map.
"""
def __init__(self, wsize, threshold_min, threshold_max, thicknessMin, thicknessMax):
StrokeShader.__init__(self)
@@ -155,7 +155,7 @@ class pyFXSVaryingThicknessWithDensityShader(StrokeShader):
class pyIncreasingThicknessShader(StrokeShader):
"""
- Increasingly thickens the stroke
+ Increasingly thickens the stroke.
"""
def __init__(self, thicknessMin, thicknessMax):
StrokeShader.__init__(self)
@@ -176,7 +176,7 @@ class pyIncreasingThicknessShader(StrokeShader):
class pyConstrainedIncreasingThicknessShader(StrokeShader):
"""
Increasingly thickens the stroke, constrained by a ratio of the
- stroke's length
+ stroke's length.
"""
def __init__(self, thicknessMin, thicknessMax, ratio):
StrokeShader.__init__(self)
@@ -203,7 +203,7 @@ class pyConstrainedIncreasingThicknessShader(StrokeShader):
class pyDecreasingThicknessShader(StrokeShader):
"""
- Inverse of pyIncreasingThicknessShader, decreasingly thickens the stroke
+ Inverse of pyIncreasingThicknessShader, decreasingly thickens the stroke.
"""
def __init__(self, thicknessMin, thicknessMax):
StrokeShader.__init__(self)
@@ -224,7 +224,7 @@ class pyDecreasingThicknessShader(StrokeShader):
class pyNonLinearVaryingThicknessShader(StrokeShader):
"""
- Assigns thickness to a stroke based on an exponential function
+ Assigns thickness to a stroke based on an exponential function.
"""
def __init__(self, thicknessExtremity, thicknessMiddle, exponent):
self._thicknessMin = thicknessMiddle
@@ -243,7 +243,7 @@ class pyNonLinearVaryingThicknessShader(StrokeShader):
class pySLERPThicknessShader(StrokeShader):
"""
- Assigns thickness to a stroke based on spherical linear interpolation
+ Assigns thickness to a stroke based on spherical linear interpolation.
"""
def __init__(self, thicknessMin, thicknessMax, omega=1.2):
StrokeShader.__init__(self)
@@ -267,7 +267,7 @@ class pySLERPThicknessShader(StrokeShader):
class pyTVertexThickenerShader(StrokeShader):
"""
- Thickens TVertices (visual intersections between two edges)
+ Thickens TVertices (visual intersections between two edges).
"""
def __init__(self, a=1.5, n=3):
StrokeShader.__init__(self)
@@ -297,7 +297,7 @@ class pyImportance2DThicknessShader(StrokeShader):
"""
Assigns thickness based on distance to a given point in 2D space.
the thickness is inverted, so the vertices closest to the
- specified point have the lowest thickness
+ specified point have the lowest thickness.
"""
def __init__(self, x, y, w, kmin, kmax):
StrokeShader.__init__(self)
@@ -317,7 +317,7 @@ class pyImportance2DThicknessShader(StrokeShader):
class pyImportance3DThicknessShader(StrokeShader):
"""
- Assigns thickness based on distance to a given point in 3D space
+ Assigns thickness based on distance to a given point in 3D space.
"""
def __init__(self, x, y, z, w, kmin, kmax):
StrokeShader.__init__(self)
@@ -338,7 +338,7 @@ class pyImportance3DThicknessShader(StrokeShader):
class pyZDependingThicknessShader(StrokeShader):
"""
Assigns thickness based on an object's local Z depth (point
- closest to camera is 1, point furthest from camera is zero)
+ closest to camera is 1, point furthest from camera is zero).
"""
def __init__(self, min, max):
StrokeShader.__init__(self)
@@ -363,7 +363,7 @@ class pyZDependingThicknessShader(StrokeShader):
class pyConstantColorShader(StrokeShader):
"""
- Assigns a constant color to the stroke
+ Assigns a constant color to the stroke.
"""
def __init__(self,r,g,b, a = 1):
StrokeShader.__init__(self)
@@ -377,7 +377,7 @@ class pyConstantColorShader(StrokeShader):
class pyIncreasingColorShader(StrokeShader):
"""
- Fades from one color to another along the stroke
+ Fades from one color to another along the stroke.
"""
def __init__(self,r1,g1,b1,a1, r2,g2,b2,a2):
StrokeShader.__init__(self)
@@ -397,7 +397,7 @@ class pyIncreasingColorShader(StrokeShader):
class pyInterpolateColorShader(StrokeShader):
"""
- Fades from one color to another and back
+ Fades from one color to another and back.
"""
def __init__(self,r1,g1,b1,a1, r2,g2,b2,a2):
StrokeShader.__init__(self)
@@ -431,7 +431,7 @@ class pyModulateAlphaShader(StrokeShader):
class pyMaterialColorShader(StrokeShader):
"""
- Assigns the color of the underlying material to the stroke
+ Assigns the color of the underlying material to the stroke.
"""
def __init__(self, threshold=50):
StrokeShader.__init__(self)
@@ -493,7 +493,7 @@ class pyMaterialColorShader(StrokeShader):
class pyRandomColorShader(StrokeShader):
"""
- Assigns a color to the stroke based on given seed
+ Assigns a color to the stroke based on given seed.
"""
def __init__(self, s=1):
StrokeShader.__init__(self)
@@ -510,7 +510,7 @@ class pyRandomColorShader(StrokeShader):
class py2DCurvatureColorShader(StrokeShader):
"""
Assigns a color (greyscale) to the stroke based on the curvature.
- A higher curvature will yield a brighter color
+ A higher curvature will yield a brighter color.
"""
def shade(self, stroke):
func = Curvature2DAngleF0D()
@@ -526,7 +526,7 @@ class py2DCurvatureColorShader(StrokeShader):
class pyTimeColorShader(StrokeShader):
"""
Assigns a greyscale value that increases for every vertex.
- The brightness will increase along the stroke
+ The brightness will increase along the stroke.
"""
def __init__(self, step=0.01):
StrokeShader.__init__(self)
@@ -543,7 +543,7 @@ class pyTimeColorShader(StrokeShader):
class pySamplingShader(StrokeShader):
"""
Resamples the stroke, which gives the stroke the ammount of
- vertices specified
+ vertices specified.
"""
def __init__(self, sampling):
StrokeShader.__init__(self)
@@ -556,7 +556,7 @@ class pySamplingShader(StrokeShader):
class pyBackboneStretcherShader(StrokeShader):
"""
- Stretches the stroke's backbone by a given length (in pixels)
+ Stretches the stroke's backbone by a given length (in pixels).
"""
def __init__(self, l):
StrokeShader.__init__(self)
@@ -617,7 +617,7 @@ class pyGuidingLineShader(StrokeShader):
class pyBackboneStretcherNoCuspShader(StrokeShader):
"""
- Stretches the stroke's backbone, excluding cusp vertices (end junctions)
+ Stretches the stroke's backbone, excluding cusp vertices (end junctions).
"""
def __init__(self, l):
StrokeShader.__init__(self)
@@ -663,7 +663,7 @@ class pyDiffusion2Shader(StrokeShader):
class pyTipRemoverShader(StrokeShader):
"""
- Removes the tips of the stroke
+ Removes the tips of the stroke.
"""
def __init__(self, l):
StrokeShader.__init__(self)
@@ -704,7 +704,7 @@ class pyTipRemoverShader(StrokeShader):
class pyTVertexRemoverShader(StrokeShader):
"""
- Removes t-vertices from the stroke
+ Removes t-vertices from the stroke.
"""
def shade(self, stroke):
if len(stroke) < 4:
@@ -721,7 +721,7 @@ class pyTVertexRemoverShader(StrokeShader):
class pyHLRShader(StrokeShader):
"""
Controlls visibility based upon the quantative invisibility (QI)
- based on hidden line removal (HLR)
+ based on hidden line removal (HLR).
"""
def shade(self, stroke):
if len(stroke) < 4:
@@ -736,7 +736,7 @@ class pyHLRShader(StrokeShader):
class pySinusDisplacementShader(StrokeShader):
"""
- Displaces the stroke in the shape of a sine wave
+ Displaces the stroke in the shape of a sine wave.
"""
def __init__(self, f, a):
StrokeShader.__init__(self)
@@ -758,7 +758,7 @@ class pyPerlinNoise1DShader(StrokeShader):
"""
Displaces the stroke using the curvilinear abscissa. This means
that lines with the same length and sampling interval will be
- identically distorded
+ identically distorded.
"""
def __init__(self, freq=10, amp=10, oct=4, seed=-1):
StrokeShader.__init__(self)
@@ -778,9 +778,9 @@ class pyPerlinNoise1DShader(StrokeShader):
class pyPerlinNoise2DShader(StrokeShader):
"""
Displaces the stroke using the strokes coordinates. This means
- that in a scene no strokes will be distorded identically
+ that in a scene no strokes will be distorded identically.
- More information on the noise shaders can be found at
+ More information on the noise shaders can be found at:
freestyleintegration.wordpress.com/2011/09/25/development-updates-on-september-25/
"""
def __init__(self, freq=10, amp=10, oct=4, seed=-1):
@@ -799,7 +799,7 @@ class pyPerlinNoise2DShader(StrokeShader):
class pyBluePrintCirclesShader(StrokeShader):
"""
- Draws the silhouette of the object as a circle
+ Draws the silhouette of the object as a circle.
"""
def __init__(self, turns=1, random_radius=3, random_center=5):
StrokeShader.__init__(self)
@@ -983,7 +983,7 @@ class pyBluePrintSquaresShader(StrokeShader):
class pyBluePrintDirectedSquaresShader(StrokeShader):
"""
- Replaces the stroke with a directed square
+ Replaces the stroke with a directed square.
"""
def __init__(self, turns=1, bb_len=10, mult=1):
StrokeShader.__init__(self)
diff --git a/release/scripts/freestyle/modules/freestyle/types.py b/release/scripts/freestyle/modules/freestyle/types.py
index 470b7ae14d6..8f596fd275c 100644
--- a/release/scripts/freestyle/modules/freestyle/types.py
+++ b/release/scripts/freestyle/modules/freestyle/types.py
@@ -17,7 +17,7 @@
# ##### END GPL LICENSE BLOCK #####
"""
-Submodule containing all Freestyle types
+Submodule containing all Freestyle types.
"""
# module members
diff --git a/release/scripts/freestyle/modules/freestyle/utils.py b/release/scripts/freestyle/modules/freestyle/utils.py
index 1b576791e9b..e6dca93b777 100644
--- a/release/scripts/freestyle/modules/freestyle/utils.py
+++ b/release/scripts/freestyle/modules/freestyle/utils.py
@@ -17,7 +17,7 @@
# ##### END GPL LICENSE BLOCK #####
"""
-Helper functions used for Freestyle style module writing
+Helper functions used for Freestyle style module writing.
"""
# module members
@@ -27,21 +27,28 @@ from _freestyle import (
integrate,
)
+from freestyle.types import (
+ Interface0DIterator,
+ Stroke,
+ StrokeVertexIterator,
+ )
+
+
from mathutils import Vector
-from functools import lru_cache
+from functools import lru_cache, namedtuple
from math import cos, sin, pi
+from itertools import tee
# -- real utility functions -- #
-
def rgb_to_bw(r, g, b):
- """ Method to convert rgb to a bw intensity value. """
+ """Method to convert rgb to a bw intensity value."""
return 0.35 * r + 0.45 * g + 0.2 * b
def bound(lower, x, higher):
- """ Returns x bounded by a maximum and minimum value. equivalent to:
+ """Returns x bounded by a maximum and minimum value. Equivalent to:
return min(max(x, lower), higher)
"""
# this is about 50% quicker than min(max(x, lower), higher)
@@ -55,7 +62,6 @@ def bounding_box(stroke):
x, y = zip(*(svert.point for svert in stroke))
return (Vector((min(x), min(y))), Vector((max(x), max(y))))
-
# -- General helper functions -- #
@@ -72,12 +78,14 @@ def phase_to_direction(length):
results.append((phase, Vector((cos(2 * pi * phase), sin(2 * pi * phase)))))
return results
+# A named tuple primitive used for storing data that has an upper and
+# lower bound (e.g., thickness, range and certain values)
+BoundedProperty = namedtuple("BoundedProperty", ["min", "max", "delta"])
# -- helper functions for chaining -- #
-
def get_chain_length(ve, orientation):
- """Returns the 2d length of a given ViewEdge """
+ """Returns the 2d length of a given ViewEdge."""
from freestyle.chainingiterators import pyChainSilhouetteGenericIterator
length = 0.0
# setup iterator
@@ -112,156 +120,121 @@ def get_chain_length(ve, orientation):
def find_matching_vertex(id, it):
- """Finds the matching vertexn, or returns None """
+ """Finds the matching vertex, or returns None."""
return next((ve for ve in it if ve.id == id), None)
-
# -- helper functions for iterating -- #
+def pairwise(iterable, types={Stroke, StrokeVertexIterator}):
+ """Yields a tuple containing the previous and current object """
+ # use .incremented() for types that support it
+ if type(iterable) in types:
+ it = iter(iterable)
+ return zip(it, it.incremented())
+ else:
+ a, b = tee(iterable)
+ next(b, None)
+ return zip(a, b)
-def iter_current_previous(stroke):
- """
- iterates over the given iterator. yields a tuple of the form
- (it, prev, current)
- """
- prev = stroke[0]
- it = Interface0DIterator(stroke)
- for current in it:
- yield (it, prev, current)
+
+def tripplewise(iterable):
+ """Yields a tuple containing the current object and its immediate neighbors """
+ a, b, c = tee(iterable)
+ next(b, None)
+ next(c, None)
+ return zip(a, b, c)
def iter_t2d_along_stroke(stroke):
- """
- Yields the distance between two stroke vertices
- relative to the total stroke length.
- """
+ """Yields the progress along the stroke."""
total = stroke.length_2d
distance = 0.0
- for it, prev, svert in iter_current_previous(stroke):
+ # yield for the comparison from the first vertex to itself
+ yield 0.0
+ for prev, svert in pairwise(stroke):
distance += (prev.point - svert.point).length
- t = min(distance / total, 1.0) if total > 0.0 else 0.0
- yield (it, t)
+ yield min(distance / total, 1.0) if total != 0.0 else 0.0
-def iter_distance_from_camera(stroke, range_min, range_max):
+def iter_distance_from_camera(stroke, range_min, range_max, normfac):
"""
Yields the distance to the camera relative to the maximum
possible distance for every stroke vertex, constrained by
given minimum and maximum values.
"""
- normfac = range_max - range_min # normalization factor
- it = Interface0DIterator(stroke)
- for svert in it:
- distance = svert.point_3d.length # in the camera coordinate
- if distance < range_min:
- t = 0.0
- elif distance > range_max:
- t = 1.0
+ for svert in stroke:
+ # length in the camera coordinate
+ distance = svert.point_3d.length
+ if range_min < distance < range_max:
+ yield (svert, (distance - range_min) / normfac)
else:
- t = (distance - range_min) / normfac
- yield (it, t)
+ yield (svert, 0.0) if range_min > distance else (svert, 1.0)
-def iter_distance_from_object(stroke, object, range_min, range_max):
+def iter_distance_from_object(stroke, location, range_min, range_max, normfac):
"""
yields the distance to the given object relative to the maximum
possible distance for every stroke vertex, constrained by
given minimum and maximum values.
"""
- scene = getCurrentScene()
- mv = scene.camera.matrix_world.copy().inverted() # model-view matrix
- loc = mv * object.location # loc in the camera coordinate
- normfac = range_max - range_min # normalization factor
- it = Interface0DIterator(stroke)
- for svert in it:
- distance = (svert.point_3d - loc).length # in the camera coordinate
- if distance < range_min:
- t = 0.0
- elif distance > range_max:
- t = 1.0
- else:
- t = (distance - range_min) / normfac
- yield (it, t)
-
-
-def iter_material_color(stroke, material_attribute):
- """
- yields the specified material attribute for every stroke vertex.
- the material is taken from the object behind the vertex.
- """
- func = CurveMaterialF0D()
- it = Interface0DIterator(stroke)
- for inter in it:
- material = func(it)
- if material_attribute == 'DIFF':
- color = material.diffuse[0:3]
- elif material_attribute == 'SPEC':
- color = material.specular[0:3]
+ for svert in stroke:
+ distance = (svert.point_3d - location).length # in the camera coordinate
+ if range_min < distance < range_max:
+ yield (svert, (distance - range_min) / normfac)
else:
- raise ValueError("unexpected material attribute: " + material_attribute)
- yield (it, color)
+ yield (svert, 0.0) if distance < range_min else (svert, 1.0)
-def iter_material_value(stroke, material_attribute):
- """
- yields a specific material attribute
- from the vertex' underlying material.
- """
- func = CurveMaterialF0D()
+def iter_material_value(stroke, func, attribute):
+ "Yields a specific material attribute from the vertex' underlying material."
it = Interface0DIterator(stroke)
for svert in it:
material = func(it)
- if material_attribute == 'DIFF':
- t = rgb_to_bw(*material.diffuse[0:3])
- elif material_attribute == 'DIFF_R':
- t = material.diffuse[0]
- elif material_attribute == 'DIFF_G':
- t = material.diffuse[1]
- elif material_attribute == 'DIFF_B':
- t = material.diffuse[2]
- elif material_attribute == 'SPEC':
- t = rgb_to_bw(*material.specular[0:3])
- elif material_attribute == 'SPEC_R':
- t = material.specular[0]
- elif material_attribute == 'SPEC_G':
- t = material.specular[1]
- elif material_attribute == 'SPEC_B':
- t = material.specular[2]
- elif material_attribute == 'SPEC_HARDNESS':
- t = material.shininess
- elif material_attribute == 'ALPHA':
- t = material.diffuse[3]
+ # main
+ if attribute == 'LINE':
+ value = rgb_to_bw(*material.line[0:3])
+ elif attribute == 'ALPHA':
+ value = material.line[3]
+ elif attribute == 'DIFF':
+ value = rgb_to_bw(*material.diffuse[0:3])
+ elif attribute == 'SPEC':
+ value = rgb_to_bw(*material.specular[0:3])
+ # line seperate
+ elif attribute == 'LINE_R':
+ value = material.line[0]
+ elif attribute == 'LINE_G':
+ value = material.line[1]
+ elif attribute == 'LINE_B':
+ value = material.line[2]
+ # diffuse seperate
+ elif attribute == 'DIFF_R':
+ value = material.diffuse[0]
+ elif attribute == 'DIFF_G':
+ value = material.diffuse[1]
+ elif attribute == 'DIFF_B':
+ value = material.diffuse[2]
+ # specular seperate
+ elif attribute == 'SPEC_R':
+ value = material.specular[0]
+ elif attribute == 'SPEC_G':
+ value = material.specular[1]
+ elif attribute == 'SPEC_B':
+ value = material.specular[2]
+ elif attribute == 'SPEC_HARDNESS':
+ value = material.shininess
else:
- raise ValueError("unexpected material attribute: " + material_attribute)
- yield (it, t)
-
+ raise ValueError("unexpected material attribute: " + attribute)
+ yield (svert, value)
def iter_distance_along_stroke(stroke):
- """
- yields the absolute distance between
- the current and preceding vertex.
- """
+ "Yields the absolute distance along the stroke up to the current vertex."
distance = 0.0
- prev = stroke[0]
- it = Interface0DIterator(stroke)
- for svert in it:
- p = svert.point
- distance += (prev - p).length
- prev = p.copy() # need a copy because the point can be altered
- yield it, distance
-
-
-def iter_triplet(it):
- """
- Iterates over it, yielding a tuple containing
- the current vertex and its immediate neighbors
- """
- prev = next(it)
- current = next(it)
- for succ in it:
- yield prev, current, succ
- prev, current = current, succ
-
+ # the positions need to be copied, because they are changed in the calling function
+ points = tuple(svert.point.copy() for svert in stroke)
+ yield distance
+ for prev, curr in pairwise(points):
+ distance += (prev - curr).length
+ yield distance
# -- mathmatical operations -- #
@@ -272,55 +245,73 @@ def stroke_curvature(it):
K = 1 / R
where R is the radius of the circle going through the current vertex and its neighbors
"""
+ for _ in it:
+ if (it.is_begin or it.is_end):
+ yield 0.0
+ continue
+ else:
+ it.decrement()
+ prev, current, succ = it.object.point.copy(), next(it).point.copy(), next(it).point.copy()
+ # return the iterator in an unchanged state
+ it.decrement()
- if it.is_end or it.is_begin:
- return 0.0
-
- next = it.incremented().point
- prev = it.decremented().point
- current = it.object.point
-
-
- ab = (current - prev)
- bc = (next - current)
- ac = (prev - next)
-
- a, b, c = ab.length, bc.length, ac.length
-
- try:
- area = 0.5 * ab.cross(ac)
- K = (4 * area) / (a * b * c)
- K = bound(0.0, K, 1.0)
+ ab = (current - prev)
+ bc = (succ - current)
+ ac = (prev - succ)
- except ZeroDivisionError:
- K = 0.0
+ a, b, c = ab.length, bc.length, ac.length
- return K
+ try:
+ area = 0.5 * ab.cross(ac)
+ K = (4 * area) / (a * b * c)
+ except ZeroDivisionError:
+ K = 0.0
+ yield abs(K)
-def stroke_normal(it):
+def stroke_normal(stroke):
"""
Compute the 2D normal at the stroke vertex pointed by the iterator
'it'. It is noted that Normal2DF0D computes normals based on
underlying FEdges instead, which is inappropriate for strokes when
they have already been modified by stroke geometry modifiers.
+
+ The returned normals are dynamic: they update when the
+ vertex position (and therefore the vertex normal) changes.
+ for use in geometry modifiers it is advised to
+ cast this generator function to a tuple or list
"""
- # first stroke segment
- it_next = it.incremented()
- if it.is_begin:
- e = it_next.object.point_2d - it.object.point_2d
- n = Vector((e[1], -e[0]))
- return n.normalized()
- # last stroke segment
- it_prev = it.decremented()
- if it_next.is_end:
- e = it.object.point_2d - it_prev.object.point_2d
- n = Vector((e[1], -e[0]))
- return n.normalized()
- # two subsequent stroke segments
- e1 = it_next.object.point_2d - it.object.point_2d
- e2 = it.object.point_2d - it_prev.object.point_2d
- n1 = Vector((e1[1], -e1[0])).normalized()
- n2 = Vector((e2[1], -e2[0])).normalized()
- n = (n1 + n2)
- return n.normalized()
+ n = len(stroke) - 1
+
+ for i, svert in enumerate(stroke):
+ if i == 0:
+ e = stroke[i + 1].point - svert.point
+ yield Vector((e[1], -e[0])).normalized()
+ elif i == n:
+ e = svert.point - stroke[i - 1].point
+ yield Vector((e[1], -e[0])).normalized()
+ else:
+ e1 = stroke[i + 1].point - svert.point
+ e2 = svert.point - stroke[i - 1].point
+ n1 = Vector((e1[1], -e1[0])).normalized()
+ n2 = Vector((e2[1], -e2[0])).normalized()
+ yield (n1 + n2).normalized()
+
+def get_test_stroke():
+ """Returns a static stroke object for testing """
+ from freestyle.types import Stroke, Interface0DIterator, StrokeVertexIterator, SVertex, Id, StrokeVertex
+ # points for our fake stroke
+ points = (Vector((1.0, 5.0, 3.0)), Vector((1.0, 2.0, 9.0)),
+ Vector((6.0, 2.0, 3.0)), Vector((7.0, 2.0, 3.0)),
+ Vector((2.0, 6.0, 3.0)), Vector((2.0, 8.0, 3.0)))
+ ids = (Id(0, 0), Id(1, 1), Id(2, 2), Id(3, 3), Id(4, 4), Id(5, 5))
+
+ stroke = Stroke()
+ it = iter(stroke)
+
+ for svert in map(SVertex, points, ids):
+ stroke.insert_vertex(StrokeVertex(svert), it)
+ it = iter(stroke)
+
+ stroke.update_length()
+ return stroke
diff --git a/release/scripts/freestyle/modules/parameter_editor.py b/release/scripts/freestyle/modules/parameter_editor.py
index 3529221c5b5..ebd09bd0181 100644
--- a/release/scripts/freestyle/modules/parameter_editor.py
+++ b/release/scripts/freestyle/modules/parameter_editor.py
@@ -32,6 +32,8 @@ from freestyle.types import (
UnaryPredicate0D,
UnaryPredicate1D,
TVertex,
+ Material,
+ ViewEdge,
)
from freestyle.chainingiterators import (
ChainPredicateIterator,
@@ -41,10 +43,10 @@ from freestyle.chainingiterators import (
)
from freestyle.functions import (
Curvature2DAngleF0D,
- CurveMaterialF0D,
Normal2DF0D,
QuantitativeInvisibilityF1D,
VertexOrientation2DF0D,
+ CurveMaterialF0D,
)
from freestyle.predicates import (
AndUP1D,
@@ -78,70 +80,78 @@ from freestyle.shaders import (
pyBluePrintCirclesShader,
pyBluePrintEllipsesShader,
pyBluePrintSquaresShader,
+ RoundCapShader,
+ SquareCapShader,
)
from freestyle.utils import (
ContextFunctions,
getCurrentScene,
+ iter_distance_along_stroke,
+ iter_t2d_along_stroke,
+ iter_distance_from_camera,
+ iter_distance_from_object,
+ iter_material_value,
stroke_normal,
+ bound,
+ pairwise,
+ BoundedProperty
)
from _freestyle import (
blendRamp,
evaluateColorRamp,
evaluateCurveMappingF,
)
-import math
-import mathutils
+
import time
+from mathutils import Vector
+from math import pi, sin, cos, acos, radians
+from itertools import cycle, tee
class ColorRampModifier(StrokeShader):
+ """Primitive for the color modifiers."""
def __init__(self, blend, influence, ramp):
StrokeShader.__init__(self)
- self.__blend = blend
- self.__influence = influence
- self.__ramp = ramp
+ self.blend = blend
+ self.influence = influence
+ self.ramp = ramp
def evaluate(self, t):
- col = evaluateColorRamp(self.__ramp, t)
- col = col.xyz # omit alpha
- return col
+ col = evaluateColorRamp(self.ramp, t)
+ return col.xyz # omit alpha
def blend_ramp(self, a, b):
- return blendRamp(self.__blend, a, self.__influence, b)
+ return blendRamp(self.blend, a, self.influence, b)
class ScalarBlendModifier(StrokeShader):
- def __init__(self, blend, influence):
+ """Primitive for alpha and thickness modifiers."""
+ def __init__(self, blend_type, influence):
StrokeShader.__init__(self)
- self.__blend = blend
- self.__influence = influence
+ self.blend_type = blend_type
+ self.influence = influence
def blend(self, v1, v2):
- fac = self.__influence
+ fac = self.influence
facm = 1.0 - fac
- if self.__blend == 'MIX':
+ if self.blend_type == 'MIX':
v1 = facm * v1 + fac * v2
- elif self.__blend == 'ADD':
+ elif self.blend_type == 'ADD':
v1 += fac * v2
- elif self.__blend == 'MULTIPLY':
+ elif self.blend_type == 'MULTIPLY':
v1 *= facm + fac * v2
- elif self.__blend == 'SUBTRACT':
+ elif self.blend_type == 'SUBTRACT':
v1 -= fac * v2
- elif self.__blend == 'DIVIDE':
- if v2 != 0.0:
- v1 = facm * v1 + fac * v1 / v2
- elif self.__blend == 'DIFFERENCE':
+ elif self.blend_type == 'DIVIDE':
+ v1 = facm * v1 + fac * v1 / v2 if v2 != 0.0 else v1
+ elif self.blend_type == 'DIFFERENCE':
v1 = facm * v1 + fac * abs(v1 - v2)
- elif self.__blend == 'MININUM':
- tmp = fac * v2
- if v1 > tmp:
- v1 = tmp
- elif self.__blend == 'MAXIMUM':
- tmp = fac * v2
- if v1 < tmp:
- v1 = tmp
+ elif self.blend_type == 'MININUM':
+ v1 = min(fac * v2, v1)
+ elif self.blend_type == 'MAXIMUM':
+ v1 = max(fac * v2, v1)
else:
- raise ValueError("unknown curve blend type: " + self.__blend)
+ raise ValueError("unknown curve blend type: " + self.blend_type)
return v1
@@ -149,34 +159,28 @@ class CurveMappingModifier(ScalarBlendModifier):
def __init__(self, blend, influence, mapping, invert, curve):
ScalarBlendModifier.__init__(self, blend, influence)
assert mapping in {'LINEAR', 'CURVE'}
- self.__mapping = getattr(self, mapping)
- self.__invert = invert
- self.__curve = curve
+ self.evaluate = getattr(self, mapping)
+ self.invert = invert
+ self.curve = curve
def LINEAR(self, t):
- if self.__invert:
- return 1.0 - t
- return t
+ return (1.0 - t) if self.invert else t
def CURVE(self, t):
- return evaluateCurveMappingF(self.__curve, 0, t)
-
- def evaluate(self, t):
- return self.__mapping(t)
+ return evaluateCurveMappingF(self.curve, 0, t)
class ThicknessModifierMixIn:
def __init__(self):
scene = getCurrentScene()
- self.__persp_camera = (scene.camera.data.type == 'PERSP')
+ self.persp_camera = (scene.camera.data.type == 'PERSP')
def set_thickness(self, sv, outer, inner):
- fe = sv.first_svertex.get_fedge(sv.second_svertex)
+ fe = sv.fedge
nature = fe.nature
if (nature & Nature.BORDER):
- if self.__persp_camera:
- point = -sv.point_3d.copy()
- point.normalize()
+ if self.persp_camera:
+ point = -sv.point_3d.normalized()
dir = point.dot(fe.normal_left)
else:
dir = fe.normal_left.z
@@ -193,30 +197,42 @@ class ThicknessModifierMixIn:
class ThicknessBlenderMixIn(ThicknessModifierMixIn):
def __init__(self, position, ratio):
ThicknessModifierMixIn.__init__(self)
- self.__position = position
- self.__ratio = ratio
+ self.position = position
+ self.ratio = ratio
- def blend_thickness(self, outer, inner, v):
+ def blend_thickness(self, svert, v):
+ """Blends and sets the thickness."""
+ outer, inner = svert.attribute.thickness
+ fe = svert.fedge
v = self.blend(outer + inner, v)
- if self.__position == 'CENTER':
- outer = v * 0.5
- inner = v - outer
- elif self.__position == 'INSIDE':
- outer = 0
- inner = v
- elif self.__position == 'OUTSIDE':
- outer = v
- inner = 0
- elif self.__position == 'RELATIVE':
- outer = v * self.__ratio
- inner = v - outer
- else:
- raise ValueError("unknown thickness position: " + self.__position)
- return outer, inner
+ # Part 1: blend
+ if self.position == 'CENTER':
+ outer = inner = v * 0.5
+ elif self.position == 'INSIDE':
+ outer, inner = 0, v
+ elif self.position == 'OUTSIDE':
+ outer, inner = v, 0
+ elif self.position == 'RELATIVE':
+ outer, inner = v * self.ratio, v - (v * self.ratio)
+ else:
+ raise ValueError("unknown thickness position: " + position)
-class BaseColorShader(ConstantColorShader):
- pass
+ # Part 2: set
+ if (fe.nature & Nature.BORDER):
+ if self.persp_camera:
+ point = -svert.point_3d.normalized()
+ dir = point.dot(fe.normal_left)
+ else:
+ dir = fe.normal_left.z
+ if dir < 0.0: # the back side is visible
+ outer, inner = inner, outer
+ elif (fe.nature & Nature.SILHOUETTE):
+ if fe.is_smooth: # TODO more tests needed
+ outer, inner = inner, outer
+ else:
+ outer = inner = (outer + inner) / 2
+ svert.attribute.thickness = (outer, inner)
class BaseThicknessShader(StrokeShader, ThicknessModifierMixIn):
@@ -224,520 +240,378 @@ class BaseThicknessShader(StrokeShader, ThicknessModifierMixIn):
StrokeShader.__init__(self)
ThicknessModifierMixIn.__init__(self)
if position == 'CENTER':
- self.__outer = thickness * 0.5
- self.__inner = thickness - self.__outer
+ self.outer = thickness * 0.5
+ self.inner = thickness - self.outer
elif position == 'INSIDE':
- self.__outer = 0
- self.__inner = thickness
+ self.outer = 0
+ self.inner = thickness
elif position == 'OUTSIDE':
- self.__outer = thickness
- self.__inner = 0
+ self.outer = thickness
+ self.inner = 0
elif position == 'RELATIVE':
- self.__outer = thickness * ratio
- self.__inner = thickness - self.__outer
+ self.outer = thickness * ratio
+ self.inner = thickness - self.outer
else:
- raise ValueError("unknown thickness position: " + self.position)
+ raise ValueError("unknown thickness position: " + position)
def shade(self, stroke):
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- sv = it.object
- self.set_thickness(sv, self.__outer, self.__inner)
- it.increment()
+ for svert in stroke:
+ self.set_thickness(svert, self.outer, self.inner)
# Along Stroke modifiers
-def iter_t2d_along_stroke(stroke):
- total = stroke.length_2d
- distance = 0.0
- it = stroke.stroke_vertices_begin()
- prev = it.object.point
- while not it.is_end:
- p = it.object.point
- distance += (prev - p).length
- prev = p.copy() # need a copy because the point can be altered
- t = min(distance / total, 1.0) if total > 0.0 else 0.0
- yield it, t
- it.increment()
-
-
class ColorAlongStrokeShader(ColorRampModifier):
+ """Maps a ramp to the color of the stroke, using the curvilinear abscissa (t)."""
def shade(self, stroke):
- for it, t in iter_t2d_along_stroke(stroke):
- sv = it.object
- a = sv.attribute.color
+ for svert, t in zip(stroke, iter_t2d_along_stroke(stroke)):
+ a = svert.attribute.color
b = self.evaluate(t)
- sv.attribute.color = self.blend_ramp(a, b)
+ svert.attribute.color = self.blend_ramp(a, b)
class AlphaAlongStrokeShader(CurveMappingModifier):
+ """Maps a curve to the alpha/transparancy of the stroke, using the curvilinear abscissa (t)."""
def shade(self, stroke):
- for it, t in iter_t2d_along_stroke(stroke):
- sv = it.object
- a = sv.attribute.alpha
+ for svert, t in zip(stroke, iter_t2d_along_stroke(stroke)):
+ a = svert.attribute.alpha
b = self.evaluate(t)
- sv.attribute.alpha = self.blend(a, b)
+ svert.attribute.alpha = self.blend(a, b)
class ThicknessAlongStrokeShader(ThicknessBlenderMixIn, CurveMappingModifier):
+ """Maps a curve to the thickness of the stroke, using the curvilinear abscissa (t)."""
def __init__(self, thickness_position, thickness_ratio,
blend, influence, mapping, invert, curve, value_min, value_max):
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
- self.__value_min = value_min
- self.__value_max = value_max
+ self.value = BoundedProperty(value_min, value_max, value_max - value_min)
def shade(self, stroke):
- for it, t in iter_t2d_along_stroke(stroke):
- sv = it.object
- a = sv.attribute.thickness
- b = self.__value_min + self.evaluate(t) * (self.__value_max - self.__value_min)
- c = self.blend_thickness(a[0], a[1], b)
- self.set_thickness(sv, c[0], c[1])
-
-
-# Distance from Camera modifiers
-
-def iter_distance_from_camera(stroke, range_min, range_max):
- normfac = range_max - range_min # normalization factor
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- p = it.object.point_3d # in the camera coordinate
- distance = p.length
- if distance < range_min:
- t = 0.0
- elif distance > range_max:
- t = 1.0
- else:
- t = (distance - range_min) / normfac
- yield it, t
- it.increment()
+ for svert, t in zip(stroke, iter_t2d_along_stroke(stroke)):
+ b = self.value.min + self.evaluate(t) * self.value.delta
+ self.blend_thickness(svert, b)
+
+# -- Distance from Camera modifiers -- #
class ColorDistanceFromCameraShader(ColorRampModifier):
+ """Picks a color value from a ramp based on the vertex' distance from the camera."""
def __init__(self, blend, influence, ramp, range_min, range_max):
ColorRampModifier.__init__(self, blend, influence, ramp)
- self.__range_min = range_min
- self.__range_max = range_max
+ self.range = BoundedProperty(range_min, range_max, range_max - range_min)
def shade(self, stroke):
- for it, t in iter_distance_from_camera(stroke, self.__range_min, self.__range_max):
- sv = it.object
- a = sv.attribute.color
+ it = iter_distance_from_camera(stroke, *self.range)
+ for svert, t in it:
+ a = svert.attribute.color
b = self.evaluate(t)
- sv.attribute.color = self.blend_ramp(a, b)
+ svert.attribute.color = self.blend_ramp(a, b)
class AlphaDistanceFromCameraShader(CurveMappingModifier):
+ """Picks an alpha value from a curve based on the vertex' distance from the camera"""
def __init__(self, blend, influence, mapping, invert, curve, range_min, range_max):
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
- self.__range_min = range_min
- self.__range_max = range_max
+ self.range = BoundedProperty(range_min, range_max, range_max - range_min)
def shade(self, stroke):
- for it, t in iter_distance_from_camera(stroke, self.__range_min, self.__range_max):
- sv = it.object
- a = sv.attribute.alpha
+ it = iter_distance_from_camera(stroke, *self.range)
+ for svert, t in it:
+ a = svert.attribute.alpha
b = self.evaluate(t)
- sv.attribute.alpha = self.blend(a, b)
+ svert.attribute.alpha = self.blend(a, b)
class ThicknessDistanceFromCameraShader(ThicknessBlenderMixIn, CurveMappingModifier):
+ """Picks a thickness value from a curve based on the vertex' distance from the camera."""
def __init__(self, thickness_position, thickness_ratio,
blend, influence, mapping, invert, curve, range_min, range_max, value_min, value_max):
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
- self.__range_min = range_min
- self.__range_max = range_max
- self.__value_min = value_min
- self.__value_max = value_max
+ self.range = BoundedProperty(range_min, range_max, range_max - range_min)
+ self.value = BoundedProperty(value_min, value_max, value_max - value_min)
def shade(self, stroke):
- for it, t in iter_distance_from_camera(stroke, self.__range_min, self.__range_max):
- sv = it.object
- a = sv.attribute.thickness
- b = self.__value_min + self.evaluate(t) * (self.__value_max - self.__value_min)
- c = self.blend_thickness(a[0], a[1], b)
- self.set_thickness(sv, c[0], c[1])
+ for (svert, t) in iter_distance_from_camera(stroke, *self.range):
+ b = self.value.min + self.evaluate(t) * self.value.delta
+ self.blend_thickness(svert, b)
# Distance from Object modifiers
-def iter_distance_from_object(stroke, object, range_min, range_max):
- scene = getCurrentScene()
- mv = scene.camera.matrix_world.copy() # model-view matrix
- mv.invert()
- loc = mv * object.location # loc in the camera coordinate
- normfac = range_max - range_min # normalization factor
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- p = it.object.point_3d # in the camera coordinate
- distance = (p - loc).length
- if distance < range_min:
- t = 0.0
- elif distance > range_max:
- t = 1.0
- else:
- t = (distance - range_min) / normfac
- yield it, t
- it.increment()
-
-
class ColorDistanceFromObjectShader(ColorRampModifier):
+ """Picks a color value from a ramp based on the vertex' distance from a given object."""
def __init__(self, blend, influence, ramp, target, range_min, range_max):
ColorRampModifier.__init__(self, blend, influence, ramp)
- self.__target = target
- self.__range_min = range_min
- self.__range_max = range_max
+ if target is None:
+ raise ValueError("ColorDistanceFromObjectShader: target can't be None ")
+ self.range = BoundedProperty(range_min, range_max, range_max - range_min)
+ # construct a model-view matrix
+ matrix = getCurrentScene().camera.matrix_world.inverted()
+ # get the object location in the camera coordinate
+ self.loc = matrix * target.location
def shade(self, stroke):
- if self.__target is None:
- return
- for it, t in iter_distance_from_object(stroke, self.__target, self.__range_min, self.__range_max):
- sv = it.object
- a = sv.attribute.color
+ it = iter_distance_from_object(stroke, self.loc, *self.range)
+ for svert, t in it:
+ a = svert.attribute.color
b = self.evaluate(t)
- sv.attribute.color = self.blend_ramp(a, b)
+ svert.attribute.color = self.blend_ramp(a, b)
class AlphaDistanceFromObjectShader(CurveMappingModifier):
+ """Picks an alpha value from a curve based on the vertex' distance from a given object."""
def __init__(self, blend, influence, mapping, invert, curve, target, range_min, range_max):
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
- self.__target = target
- self.__range_min = range_min
- self.__range_max = range_max
+ if target is None:
+ raise ValueError("AlphaDistanceFromObjectShader: target can't be None ")
+ self.range = BoundedProperty(range_min, range_max, range_max - range_min)
+ # construct a model-view matrix
+ matrix = getCurrentScene().camera.matrix_world.inverted()
+ # get the object location in the camera coordinate
+ self.loc = matrix * target.location
def shade(self, stroke):
- if self.__target is None:
- return
- for it, t in iter_distance_from_object(stroke, self.__target, self.__range_min, self.__range_max):
- sv = it.object
- a = sv.attribute.alpha
+ it = iter_distance_from_object(stroke, self.loc, *self.range)
+ for svert, t in it:
+ a = svert.attribute.alpha
b = self.evaluate(t)
- sv.attribute.alpha = self.blend(a, b)
+ svert.attribute.alpha = self.blend(a, b)
class ThicknessDistanceFromObjectShader(ThicknessBlenderMixIn, CurveMappingModifier):
+ """Picks a thickness value from a curve based on the vertex' distance from a given object."""
def __init__(self, thickness_position, thickness_ratio,
blend, influence, mapping, invert, curve, target, range_min, range_max, value_min, value_max):
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
- self.__target = target
- self.__range_min = range_min
- self.__range_max = range_max
- self.__value_min = value_min
- self.__value_max = value_max
+ if target is None:
+ raise ValueError("ThicknessDistanceFromObjectShader: target can't be None ")
+ self.range = BoundedProperty(range_min, range_max, range_max - range_min)
+ self.value = BoundedProperty(value_min, value_max, value_max - value_min)
+ # construct a model-view matrix
+ matrix = getCurrentScene().camera.matrix_world.inverted()
+ # get the object location in the camera coordinate
+ self.loc = matrix * target.location
def shade(self, stroke):
- if self.__target is None:
- return
- for it, t in iter_distance_from_object(stroke, self.__target, self.__range_min, self.__range_max):
- sv = it.object
- a = sv.attribute.thickness
- b = self.__value_min + self.evaluate(t) * (self.__value_max - self.__value_min)
- c = self.blend_thickness(a[0], a[1], b)
- self.set_thickness(sv, c[0], c[1])
-
+ it = iter_distance_from_object(stroke, self.loc, *self.range)
+ for svert, t in it:
+ b = self.value.min + self.evaluate(t) * self.value.delta
+ self.blend_thickness(svert, b)
# Material modifiers
-
-def iter_material_color(stroke, material_attribute):
- func = CurveMaterialF0D()
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- material = func(Interface0DIterator(it))
- if material_attribute == 'LINE':
- color = material.line[0:3]
- elif material_attribute == 'DIFF':
- color = material.diffuse[0:3]
- elif material_attribute == 'SPEC':
- color = material.specular[0:3]
- else:
- raise ValueError("unexpected material attribute: " + material_attribute)
- yield it, color
- it.increment()
-
-
-def iter_material_value(stroke, material_attribute):
- func = CurveMaterialF0D()
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- material = func(Interface0DIterator(it))
- if material_attribute == 'LINE':
- r, g, b = material.line[0:3]
- t = 0.35 * r + 0.45 * g + 0.2 * b
- elif material_attribute == 'LINE_R':
- t = material.line[0]
- elif material_attribute == 'LINE_G':
- t = material.line[1]
- elif material_attribute == 'LINE_B':
- t = material.line[2]
- elif material_attribute == 'ALPHA':
- t = material.line[3]
- elif material_attribute == 'DIFF':
- r, g, b = material.diffuse[0:3]
- t = 0.35 * r + 0.45 * g + 0.2 * b
- elif material_attribute == 'DIFF_R':
- t = material.diffuse[0]
- elif material_attribute == 'DIFF_G':
- t = material.diffuse[1]
- elif material_attribute == 'DIFF_B':
- t = material.diffuse[2]
- elif material_attribute == 'SPEC':
- r, g, b = material.specular[0:3]
- t = 0.35 * r + 0.45 * g + 0.2 * b
- elif material_attribute == 'SPEC_R':
- t = material.specular[0]
- elif material_attribute == 'SPEC_G':
- t = material.specular[1]
- elif material_attribute == 'SPEC_B':
- t = material.specular[2]
- elif material_attribute == 'SPEC_HARDNESS':
- t = material.shininess
- else:
- raise ValueError("unexpected material attribute: " + material_attribute)
- yield it, t
- it.increment()
-
-
class ColorMaterialShader(ColorRampModifier):
+ """Assigns a color to the vertices based on their underlying material."""
def __init__(self, blend, influence, ramp, material_attribute, use_ramp):
ColorRampModifier.__init__(self, blend, influence, ramp)
- self.__material_attribute = material_attribute
- self.__use_ramp = use_ramp
-
- def shade(self, stroke):
- if self.__material_attribute in {'LINE', 'DIFF', 'SPEC'} and not self.__use_ramp:
- for it, b in iter_material_color(stroke, self.__material_attribute):
- sv = it.object
- a = sv.attribute.color
- sv.attribute.color = self.blend_ramp(a, b)
+ self.attribute = material_attribute
+ self.use_ramp = use_ramp
+ self.func = CurveMaterialF0D()
+
+ def shade(self, stroke, attributes={'DIFF', 'SPEC', 'LINE'}):
+ it = Interface0DIterator(stroke)
+ if not self.use_ramp and self.attribute in attributes:
+ for svert in it:
+ material = self.func(it)
+ if self.attribute == 'LINE':
+ b = material.line[0:3]
+ elif self.attribute == 'DIFF':
+ b = material.diffuse[0:3]
+ else:
+ b = material.specular[0:3]
+ a = svert.attribute.color
+ svert.attribute.color = self.blend_ramp(a, b)
else:
- for it, t in iter_material_value(stroke, self.__material_attribute):
- sv = it.object
- a = sv.attribute.color
- b = self.evaluate(t)
- sv.attribute.color = self.blend_ramp(a, b)
-
+ for svert, value in iter_material_value(stroke, self.func, self.attribute):
+ a = svert.attribute.color
+ b = self.evaluate(value)
+ svert.attribute.color = self.blend_ramp(a, b)
class AlphaMaterialShader(CurveMappingModifier):
+ """Assigns an alpha value to the vertices based on their underlying material."""
def __init__(self, blend, influence, mapping, invert, curve, material_attribute):
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
- self.__material_attribute = material_attribute
+ self.attribute = material_attribute
+ self.func = CurveMaterialF0D()
def shade(self, stroke):
- for it, t in iter_material_value(stroke, self.__material_attribute):
- sv = it.object
- a = sv.attribute.alpha
- b = self.evaluate(t)
- sv.attribute.alpha = self.blend(a, b)
+ for svert, value in iter_material_value(stroke, self.func, self.attribute):
+ a = svert.attribute.alpha
+ b = self.evaluate(value)
+ svert.attribute.alpha = self.blend(a, b)
class ThicknessMaterialShader(ThicknessBlenderMixIn, CurveMappingModifier):
+ """Assigns a thickness value to the vertices based on their underlying material."""
def __init__(self, thickness_position, thickness_ratio,
blend, influence, mapping, invert, curve, material_attribute, value_min, value_max):
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
- self.__material_attribute = material_attribute
- self.__value_min = value_min
- self.__value_max = value_max
+ self.attribute = material_attribute
+ self.value = BoundedProperty(value_min, value_max, value_max - value_min)
+ self.func = CurveMaterialF0D()
def shade(self, stroke):
- for it, t in iter_material_value(stroke, self.__material_attribute):
- sv = it.object
- a = sv.attribute.thickness
- b = self.__value_min + self.evaluate(t) * (self.__value_max - self.__value_min)
- c = self.blend_thickness(a[0], a[1], b)
- self.set_thickness(sv, c[0], c[1])
+ for svert, value in iter_material_value(stroke, self.func, self.attribute):
+ b = self.value.min + self.evaluate(value) * self.value.delta
+ self.blend_thickness(svert, b)
# Calligraphic thickness modifier
+
class CalligraphicThicknessShader(ThicknessBlenderMixIn, ScalarBlendModifier):
+ """Thickness modifier for achieving a calligraphy-like effect."""
def __init__(self, thickness_position, thickness_ratio,
- blend, influence, orientation, thickness_min, thickness_max):
+ blend_type, influence, orientation, thickness_min, thickness_max):
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
- ScalarBlendModifier.__init__(self, blend, influence)
- self.__orientation = mathutils.Vector((math.cos(orientation), math.sin(orientation)))
- self.__thickness_min = thickness_min
- self.__thickness_max = thickness_max
+ ScalarBlendModifier.__init__(self, blend_type, influence)
+ self.orientation = Vector((cos(orientation), sin(orientation)))
+ self.thickness = BoundedProperty(thickness_min, thickness_max, thickness_max - thickness_min)
+ self.func = VertexOrientation2DF0D()
def shade(self, stroke):
- func = VertexOrientation2DF0D()
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- dir = func(Interface0DIterator(it))
- orthDir = mathutils.Vector((-dir.y, dir.x))
- orthDir.normalize()
- fac = abs(orthDir * self.__orientation)
- sv = it.object
- a = sv.attribute.thickness
- b = self.__thickness_min + fac * (self.__thickness_max - self.__thickness_min)
- b = max(b, 0.0)
- c = self.blend_thickness(a[0], a[1], b)
- self.set_thickness(sv, c[0], c[1])
- it.increment()
+ it = Interface0DIterator(stroke)
+ for svert in it:
+ dir = self.func(it)
+ if dir.length != 0.0:
+ dir.normalize()
+ fac = abs(dir.orthogonal() * self.orientation)
+ b = self.thickness.min + fac * self.thickness.delta
+ else:
+ b = self.thickness.min
+ self.blend_thickness(svert, b)
# Geometry modifiers
-def iter_distance_along_stroke(stroke):
- distance = 0.0
- it = stroke.stroke_vertices_begin()
- prev = it.object.point
- while not it.is_end:
- p = it.object.point
- distance += (prev - p).length
- prev = p.copy() # need a copy because the point can be altered
- yield it, distance
- it.increment()
-
-
class SinusDisplacementShader(StrokeShader):
+ """Displaces the stroke in a sinewave-like shape."""
def __init__(self, wavelength, amplitude, phase):
StrokeShader.__init__(self)
- self._wavelength = wavelength
- self._amplitude = amplitude
- self._phase = phase / wavelength * 2 * math.pi
+ self.wavelength = wavelength
+ self.amplitude = amplitude
+ self.phase = phase / wavelength * 2 * pi
def shade(self, stroke):
- # separately iterate over stroke vertices to compute normals
- buf = []
- for it, distance in iter_distance_along_stroke(stroke):
- buf.append((it.object, distance, stroke_normal(it)))
- # iterate over the vertices again to displace them
- for v, distance, normal in buf:
- n = normal * self._amplitude * math.cos(distance / self._wavelength * 2 * math.pi + self._phase)
- v.point = v.point + n
+ # normals are stored in a tuple, so they don't update when we reposition vertices.
+ normals = tuple(stroke_normal(stroke))
+ distances = iter_distance_along_stroke(stroke)
+ coeff = 1 / self.wavelength * 2 * pi
+ for svert, distance, normal in zip(stroke, distances, normals):
+ n = normal * self.amplitude * cos(distance * coeff + self.phase)
+ svert.point += n
stroke.update_length()
class PerlinNoise1DShader(StrokeShader):
- def __init__(self, freq=10, amp=10, oct=4, angle=math.radians(45), seed=-1):
+ """
+ Displaces the stroke using the curvilinear abscissa. This means
+ that lines with the same length and sampling interval will be
+ identically distorded.
+ """
+ def __init__(self, freq=10, amp=10, oct=4, angle=radians(45), seed=-1):
StrokeShader.__init__(self)
- self.__noise = Noise(seed)
- self.__freq = freq
- self.__amp = amp
- self.__oct = oct
- self.__dir = mathutils.Vector((math.cos(angle), math.sin(angle)))
+ self.noise = Noise(seed)
+ self.freq = freq
+ self.amp = amp
+ self.oct = oct
+ self.dir = Vector((cos(angle), sin(angle)))
def shade(self, stroke):
length = stroke.length_2d
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- v = it.object
- nres = self.__noise.turbulence1(length * v.u, self.__freq, self.__amp, self.__oct)
- v.point = v.point + nres * self.__dir
- it.increment()
+ for svert in stroke:
+ nres = self.noise.turbulence1(length * svert.u, self.freq, self.amp, self.oct)
+ svert.point += nres * self.dir
stroke.update_length()
class PerlinNoise2DShader(StrokeShader):
- def __init__(self, freq=10, amp=10, oct=4, angle=math.radians(45), seed=-1):
+ """
+ Displaces the stroke using the strokes coordinates. This means
+ that in a scene no strokes will be distorded identically.
+
+ More information on the noise shaders can be found at:
+ freestyleintegration.wordpress.com/2011/09/25/development-updates-on-september-25/
+ """
+ def __init__(self, freq=10, amp=10, oct=4, angle=radians(45), seed=-1):
StrokeShader.__init__(self)
- self.__noise = Noise(seed)
- self.__freq = freq
- self.__amp = amp
- self.__oct = oct
- self.__dir = mathutils.Vector((math.cos(angle), math.sin(angle)))
+ self.noise = Noise(seed)
+ self.freq = freq
+ self.amp = amp
+ self.oct = oct
+ self.dir = Vector((cos(angle), sin(angle)))
def shade(self, stroke):
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- v = it.object
- vec = mathutils.Vector((v.projected_x, v.projected_y))
- nres = self.__noise.turbulence2(vec, self.__freq, self.__amp, self.__oct)
- v.point = v.point + nres * self.__dir
- it.increment()
+ for svert in stroke:
+ projected = Vector((svert.projected_x, svert.projected_y))
+ nres = self.noise.turbulence2(projected, self.freq, self.amp, self.oct)
+ svert.point += nres * self.dir
stroke.update_length()
class Offset2DShader(StrokeShader):
+ """Offsets the stroke by a given amount."""
def __init__(self, start, end, x, y):
StrokeShader.__init__(self)
- self.__start = start
- self.__end = end
- self.__xy = mathutils.Vector((x, y))
+ self.start = start
+ self.end = end
+ self.xy = Vector((x, y))
def shade(self, stroke):
- # first iterate over stroke vertices to compute normals
- buf = []
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- buf.append((it.object, stroke_normal(it)))
- it.increment()
- # again iterate over the vertices to add displacement
- for v, n in buf:
- a = self.__start + v.u * (self.__end - self.__start)
- n = n * a
- v.point = v.point + n + self.__xy
+ # normals are stored in a tuple, so they don't update when we reposition vertices.
+ normals = tuple(stroke_normal(stroke))
+ for svert, normal in zip(stroke, normals):
+ a = self.start + svert.u * (self.end - self.start)
+ svert.point += (normal * a) + self.xy
stroke.update_length()
class Transform2DShader(StrokeShader):
+ """Transforms the stroke (scale, rotation, location) around a given pivot point """
def __init__(self, pivot, scale_x, scale_y, angle, pivot_u, pivot_x, pivot_y):
StrokeShader.__init__(self)
- self.__pivot = pivot
- self.__scale_x = scale_x
- self.__scale_y = scale_y
- self.__angle = angle
- self.__pivot_u = pivot_u
- self.__pivot_x = pivot_x
- self.__pivot_y = pivot_y
+ self.pivot = pivot
+ self.scale = Vector((scale_x, scale_y))
+ self.cos_theta = cos(angle)
+ self.sin_theta = sin(angle)
+ self.pivot_u = pivot_u
+ self.pivot_x = pivot_x
+ self.pivot_y = pivot_y
+ if pivot not in {'START', 'END', 'CENTER', 'ABSOLUTE', 'PARAM'}:
+ raise ValueError("expected pivot in {'START', 'END', 'CENTER', 'ABSOLUTE', 'PARAM'}, not" + pivot)
def shade(self, stroke):
# determine the pivot of scaling and rotation operations
- if self.__pivot == 'START':
- it = stroke.stroke_vertices_begin()
- pivot = it.object.point
- elif self.__pivot == 'END':
- it = stroke.stroke_vertices_end()
- it.decrement()
- pivot = it.object.point
- elif self.__pivot == 'PARAM':
- p = None
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- prev = p
- v = it.object
- p = v.point
- u = v.u
- if self.__pivot_u < u:
- break
- it.increment()
- if prev is None:
- pivot = p
+ if self.pivot == 'START':
+ pivot = stroke[0].point
+ elif self.pivot == 'END':
+ pivot = stroke[-1].point
+ elif self.pivot == 'CENTER':
+ # minor rounding errors here, because
+ # given v = Vector(a, b), then (v / n) != Vector(v.x / n, v.y / n)
+ pivot = (1 / len(stroke)) * sum((svert.point for svert in stroke), Vector((0.0, 0.0)))
+ elif self.pivot == 'ABSOLUTE':
+ pivot = Vector((self.pivot_x, self.pivot_y))
+ elif self.pivot == 'PARAM':
+ if self.pivot_u < stroke[0].u:
+ pivot = stroke[0].point
else:
- delta = u - self.__pivot_u
- pivot = p + delta * (prev - p)
- elif self.__pivot == 'CENTER':
- pivot = mathutils.Vector((0.0, 0.0))
- n = 0
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- p = it.object.point
- pivot = pivot + p
- n += 1
- it.increment()
- pivot.x = pivot.x / n
- pivot.y = pivot.y / n
- elif self.__pivot == 'ABSOLUTE':
- pivot = mathutils.Vector((self.__pivot_x, self.__pivot_y))
+ for prev, svert in pairwise(stroke):
+ if self.pivot_u < svert.u:
+ break
+ pivot = svert.point + (svert.u - self.pivot_u) * (prev.point - svert.point)
+
# apply scaling and rotation operations
- cos_theta = math.cos(self.__angle)
- sin_theta = math.sin(self.__angle)
- it = stroke.stroke_vertices_begin()
- while not it.is_end:
- v = it.object
- p = v.point
- p = p - pivot
- x = p.x * self.__scale_x
- y = p.y * self.__scale_y
- p.x = x * cos_theta - y * sin_theta
- p.y = x * sin_theta + y * cos_theta
- v.point = p + pivot
- it.increment()
+ for svert in stroke:
+ p = (svert.point - pivot)
+ x = p.x * self.scale.x
+ y = p.y * self.scale.y
+ p.x = x * self.cos_theta - y * self.sin_theta
+ p.y = x * self.sin_theta + y * self.cos_theta
+ svert.point = p + pivot
stroke.update_length()
@@ -746,165 +620,46 @@ class Transform2DShader(StrokeShader):
class QuantitativeInvisibilityRangeUP1D(UnaryPredicate1D):
def __init__(self, qi_start, qi_end):
UnaryPredicate1D.__init__(self)
- self.__getQI = QuantitativeInvisibilityF1D()
- self.__qi_start = qi_start
- self.__qi_end = qi_end
+ self.getQI = QuantitativeInvisibilityF1D()
+ self.qi_start = qi_start
+ self.qi_end = qi_end
def __call__(self, inter):
- qi = self.__getQI(inter)
- return self.__qi_start <= qi <= self.__qi_end
-
-
-def join_unary_predicates(upred_list, bpred):
- if not upred_list:
- return None
- upred = upred_list[0]
- for p in upred_list[1:]:
- upred = bpred(upred, p)
- return upred
+ qi = self.getQI(inter)
+ return self.qi_start <= qi <= self.qi_end
class ObjectNamesUP1D(UnaryPredicate1D):
def __init__(self, names, negative):
UnaryPredicate1D.__init__(self)
- self._names = names
- self._negative = negative
+ self.names = names
+ self.negative = negative
def __call__(self, viewEdge):
- found = viewEdge.viewshape.name in self._names
- if self._negative:
+ found = viewEdge.viewshape.name in self.names
+ if self.negative:
return not found
return found
-# Stroke caps
-
-def iter_stroke_vertices(stroke):
- it = stroke.stroke_vertices_begin()
- prev_p = None
- while not it.is_end:
- sv = it.object
- p = sv.point
- if prev_p is None or (prev_p - p).length > 1e-6:
- yield sv
- prev_p = p.copy()
- it.increment()
-
-
-class RoundCapShader(StrokeShader):
- def round_cap_thickness(self, x):
- x = max(0.0, min(x, 1.0))
- return math.sqrt(1.0 - (x ** 2.0))
-
- def shade(self, stroke):
- # save the location and attribute of stroke vertices
- buffer = []
- for sv in iter_stroke_vertices(stroke):
- buffer.append((mathutils.Vector(sv.point), StrokeAttribute(sv.attribute)))
- nverts = len(buffer)
- if nverts < 2:
- return
- # calculate the number of additional vertices to form caps
- R, L = stroke[0].attribute.thickness
- caplen_beg = (R + L) / 2.0
- nverts_beg = max(5, int(R + L))
- R, L = stroke[-1].attribute.thickness
- caplen_end = (R + L) / 2.0
- nverts_end = max(5, int(R + L))
- # adjust the total number of stroke vertices
- stroke.resample(nverts + nverts_beg + nverts_end)
- # restore the location and attribute of the original vertices
- for i in range(nverts):
- p, attr = buffer[i]
- stroke[nverts_beg + i].point = p
- stroke[nverts_beg + i].attribute = attr
- # reshape the cap at the beginning of the stroke
- q, attr = buffer[1]
- p, attr = buffer[0]
- d = p - q
- d = d / d.length * caplen_beg
- n = 1.0 / nverts_beg
- R, L = attr.thickness
- for i in range(nverts_beg):
- t = (nverts_beg - i) * n
- stroke[i].point = p + d * t
- r = self.round_cap_thickness((nverts_beg - i + 1) * n)
- stroke[i].attribute = attr
- stroke[i].attribute.thickness = (R * r, L * r)
- # reshape the cap at the end of the stroke
- q, attr = buffer[-2]
- p, attr = buffer[-1]
- d = p - q
- d = d / d.length * caplen_end
- n = 1.0 / nverts_end
- R, L = attr.thickness
- for i in range(nverts_end):
- t = (nverts_end - i) * n
- stroke[-i - 1].point = p + d * t
- r = self.round_cap_thickness((nverts_end - i + 1) * n)
- stroke[-i - 1].attribute = attr
- stroke[-i - 1].attribute.thickness = (R * r, L * r)
- # update the curvilinear 2D length of each vertex
- stroke.update_length()
-
-
-class SquareCapShader(StrokeShader):
- def shade(self, stroke):
- # save the location and attribute of stroke vertices
- buffer = []
- for sv in iter_stroke_vertices(stroke):
- buffer.append((mathutils.Vector(sv.point), StrokeAttribute(sv.attribute)))
- nverts = len(buffer)
- if nverts < 2:
- return
- # calculate the number of additional vertices to form caps
- R, L = stroke[0].attribute.thickness
- caplen_beg = (R + L) / 2.0
- nverts_beg = 1
- R, L = stroke[-1].attribute.thickness
- caplen_end = (R + L) / 2.0
- nverts_end = 1
- # adjust the total number of stroke vertices
- stroke.resample(nverts + nverts_beg + nverts_end)
- # restore the location and attribute of the original vertices
- for i in range(nverts):
- p, attr = buffer[i]
- stroke[nverts_beg + i].point = p
- stroke[nverts_beg + i].attribute = attr
- # reshape the cap at the beginning of the stroke
- q, attr = buffer[1]
- p, attr = buffer[0]
- d = p - q
- stroke[0].point = p + d / d.length * caplen_beg
- stroke[0].attribute = attr
- # reshape the cap at the end of the stroke
- q, attr = buffer[-2]
- p, attr = buffer[-1]
- d = p - q
- stroke[-1].point = p + d / d.length * caplen_beg
- stroke[-1].attribute = attr
- # update the curvilinear 2D length of each vertex
- stroke.update_length()
-
-
-# Split by dashed line pattern
+# -- Split by dashed line pattern -- #
class SplitPatternStartingUP0D(UnaryPredicate0D):
def __init__(self, controller):
UnaryPredicate0D.__init__(self)
- self._controller = controller
+ self.controller = controller
def __call__(self, inter):
- return self._controller.start()
+ return self.controller.start()
class SplitPatternStoppingUP0D(UnaryPredicate0D):
def __init__(self, controller):
UnaryPredicate0D.__init__(self)
- self._controller = controller
+ self.controller = controller
def __call__(self, inter):
- return self._controller.stop()
+ return self.controller.stop()
class SplitPatternController:
@@ -946,29 +701,29 @@ class SplitPatternController:
class DashedLineShader(StrokeShader):
def __init__(self, pattern):
StrokeShader.__init__(self)
- self._pattern = pattern
+ self.pattern = pattern
def shade(self, stroke):
- index = 0 # pattern index
start = 0.0 # 2D curvilinear length
visible = True
+ # The extra 'sampling' term is added below, because the
+ # visibility attribute of the i-th vertex refers to the
+ # visibility of the stroke segment between the i-th and
+ # (i+1)-th vertices.
sampling = 1.0
it = stroke.stroke_vertices_begin(sampling)
- while not it.is_end:
+ pattern_cycle = cycle(self.pattern)
+ pattern = next(pattern_cycle)
+ for svert in it:
pos = it.t # curvilinear abscissa
- # The extra 'sampling' term is added below, because the
- # visibility attribute of the i-th vertex refers to the
- # visibility of the stroke segment between the i-th and
- # (i+1)-th vertices.
- if pos - start + sampling > self._pattern[index]:
+
+ if pos - start + sampling > pattern:
start = pos
- index += 1
- if index == len(self._pattern):
- index = 0
+ pattern = next(pattern_cycle)
visible = not visible
+
if not visible:
- it.object.attribute.visible = visible
- it.increment()
+ it.object.attribute.visible = False
# predicates for chaining
@@ -976,7 +731,7 @@ class DashedLineShader(StrokeShader):
class AngleLargerThanBP1D(BinaryPredicate1D):
def __init__(self, angle):
BinaryPredicate1D.__init__(self)
- self._angle = angle
+ self.angle = angle
def __call__(self, i1, i2):
sv1a = i1.first_fedge.first_svertex.point_2d
@@ -1001,38 +756,28 @@ class AngleLargerThanBP1D(BinaryPredicate1D):
if denom < 1e-6:
return False
x = (dir1 * dir2) / denom
- return math.acos(min(max(x, -1.0), 1.0)) > self._angle
-
-
-class AndBP1D(BinaryPredicate1D):
- def __init__(self, pred1, pred2):
- BinaryPredicate1D.__init__(self)
- self.__pred1 = pred1
- self.__pred2 = pred2
-
- def __call__(self, i1, i2):
- return self.__pred1(i1, i2) and self.__pred2(i1, i2)
-
+ return acos(bound(-1.0, x, 1.0)) > self.angle
# predicates for selection
+
class LengthThresholdUP1D(UnaryPredicate1D):
def __init__(self, length_min=None, length_max=None):
UnaryPredicate1D.__init__(self)
- self._length_min = length_min
- self._length_max = length_max
+ self.length_min = length_min
+ self.length_max = length_max
def __call__(self, inter):
length = inter.length_2d
- if self._length_min is not None and length < self._length_min:
+ if self.length_min is not None and length < self.length_min:
return False
- if self._length_max is not None and length > self._length_max:
+ if self.length_max is not None and length > self.length_max:
return False
return True
class FaceMarkBothUP1D(UnaryPredicate1D):
- def __call__(self, inter): # ViewEdge
+ def __call__(self, inter: ViewEdge):
fe = inter.first_fedge
while fe is not None:
if fe.is_smooth:
@@ -1049,7 +794,7 @@ class FaceMarkBothUP1D(UnaryPredicate1D):
class FaceMarkOneUP1D(UnaryPredicate1D):
- def __call__(self, inter): # ViewEdge
+ def __call__(self, inter: ViewEdge):
fe = inter.first_fedge
while fe is not None:
if fe.is_smooth:
@@ -1069,17 +814,14 @@ class FaceMarkOneUP1D(UnaryPredicate1D):
class MaterialBoundaryUP0D(UnaryPredicate0D):
def __call__(self, it):
- if it.is_begin:
- return False
- it_prev = Interface0DIterator(it)
- it_prev.decrement()
- v = it.object
- it.increment()
- if it.is_end:
+ # can't use only it.is_end here, see commit rBeb8964fb7f19
+ if it.is_begin or it.at_last or it.is_end:
return False
- fe = v.get_fedge(it_prev.object)
+ it.decrement()
+ prev, v, succ = next(it), next(it), next(it)
+ fe = v.get_fedge(prev)
idx1 = fe.material_index if fe.is_smooth else fe.material_index_left
- fe = v.get_fedge(it.object)
+ fe = v.get_fedge(succ)
idx2 = fe.material_index if fe.is_smooth else fe.material_index_left
return idx1 != idx2
@@ -1087,15 +829,15 @@ class MaterialBoundaryUP0D(UnaryPredicate0D):
class Curvature2DAngleThresholdUP0D(UnaryPredicate0D):
def __init__(self, angle_min=None, angle_max=None):
UnaryPredicate0D.__init__(self)
- self._angle_min = angle_min
- self._angle_max = angle_max
- self._func = Curvature2DAngleF0D()
+ self.angle_min = angle_min
+ self.angle_max = angle_max
+ self.func = Curvature2DAngleF0D()
def __call__(self, inter):
- angle = math.pi - self._func(inter)
- if self._angle_min is not None and angle < self._angle_min:
+ angle = pi - self.func(inter)
+ if self.angle_min is not None and angle < self.angle_min:
return True
- if self._angle_max is not None and angle > self._angle_max:
+ if self.angle_max is not None and angle > self.angle_max:
return True
return False
@@ -1103,17 +845,17 @@ class Curvature2DAngleThresholdUP0D(UnaryPredicate0D):
class Length2DThresholdUP0D(UnaryPredicate0D):
def __init__(self, length_limit):
UnaryPredicate0D.__init__(self)
- self._length_limit = length_limit
- self._t = 0.0
+ self.length_limit = length_limit
+ self.t = 0.0
def __call__(self, inter):
t = inter.t # curvilinear abscissa
- if t < self._t:
- self._t = 0.0
+ if t < self.t:
+ self.t = 0.0
return False
- if t - self._t < self._length_limit:
+ if t - self.t < self.length_limit:
return False
- self._t = t
+ self.t = t
return True
@@ -1192,9 +934,9 @@ def process(layer_name, lineset_name):
upred = ExternalContourUP1D()
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_external_contour else upred)
if lineset.edge_type_combination == 'OR':
- upred = join_unary_predicates(edge_type_criteria, OrUP1D)
+ upred = OrUP1D(*edge_type_criteria)
else:
- upred = join_unary_predicates(edge_type_criteria, AndUP1D)
+ upred = AndUP1D(*edge_type_criteria)
if upred is not None:
if lineset.edge_type_negation == 'EXCLUSIVE':
upred = NotUP1D(upred)
@@ -1205,22 +947,22 @@ def process(layer_name, lineset_name):
upred = FaceMarkBothUP1D()
else:
upred = FaceMarkOneUP1D()
+
if lineset.face_mark_negation == 'EXCLUSIVE':
upred = NotUP1D(upred)
selection_criteria.append(upred)
# prepare selection criteria by group of objects
if lineset.select_by_group:
if lineset.group is not None:
- names = dict((ob.name, True) for ob in lineset.group.objects)
+ names = {ob.name: True for ob in lineset.group.objects}
upred = ObjectNamesUP1D(names, lineset.group_negation == 'EXCLUSIVE')
selection_criteria.append(upred)
# prepare selection criteria by image border
if lineset.select_by_image_border:
- xmin, ymin, xmax, ymax = ContextFunctions.get_border()
- upred = WithinImageBoundaryUP1D(xmin, ymin, xmax, ymax)
+ upred = WithinImageBoundaryUP1D(*ContextFunctions.get_border())
selection_criteria.append(upred)
# select feature edges
- upred = join_unary_predicates(selection_criteria, AndUP1D)
+ upred = AndUP1D(*selection_criteria)
if upred is None:
upred = TrueUP1D()
Operators.select(upred)
@@ -1330,15 +1072,7 @@ def process(layer_name, lineset_name):
elif m.type == '2D_TRANSFORM':
shaders_list.append(Transform2DShader(
m.pivot, m.scale_x, m.scale_y, m.angle, m.pivot_u, m.pivot_x, m.pivot_y))
- if linestyle.use_texture:
- has_tex = False
- for slot in linestyle.texture_slots:
- if slot is not None:
- shaders_list.append(BlenderTextureShader(slot))
- has_tex = True
- if has_tex:
- shaders_list.append(StrokeTextureStepShader(linestyle.texture_spacing))
- color = linestyle.color
+ # -- Base color, alpha and thickness -- #
if (not linestyle.use_chaining) or (linestyle.chaining == 'PLAIN' and linestyle.use_same_object):
thickness_position = linestyle.thickness_position
else:
@@ -1347,9 +1081,10 @@ def process(layer_name, lineset_name):
if bpy.app.debug_freestyle:
print("Warning: Thickness position options are applied when chaining is disabled\n"
" or the Plain chaining is used with the Same Object option enabled.")
- shaders_list.append(BaseColorShader(color.r, color.g, color.b, linestyle.alpha))
+ shaders_list.append(ConstantColorShader(*(linestyle.color), alpha=linestyle.alpha))
shaders_list.append(BaseThicknessShader(linestyle.thickness, thickness_position,
linestyle.thickness_ratio))
+ # -- Modifiers -- #
for m in linestyle.color_modifiers:
if not m.use:
continue
@@ -1360,7 +1095,7 @@ def process(layer_name, lineset_name):
shaders_list.append(ColorDistanceFromCameraShader(
m.blend, m.influence, m.color_ramp,
m.range_min, m.range_max))
- elif m.type == 'DISTANCE_FROM_OBJECT':
+ elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None:
shaders_list.append(ColorDistanceFromObjectShader(
m.blend, m.influence, m.color_ramp, m.target,
m.range_min, m.range_max))
@@ -1378,7 +1113,7 @@ def process(layer_name, lineset_name):
shaders_list.append(AlphaDistanceFromCameraShader(
m.blend, m.influence, m.mapping, m.invert, m.curve,
m.range_min, m.range_max))
- elif m.type == 'DISTANCE_FROM_OBJECT':
+ elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None:
shaders_list.append(AlphaDistanceFromObjectShader(
m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
m.range_min, m.range_max))
@@ -1399,7 +1134,7 @@ def process(layer_name, lineset_name):
thickness_position, linestyle.thickness_ratio,
m.blend, m.influence, m.mapping, m.invert, m.curve,
m.range_min, m.range_max, m.value_min, m.value_max))
- elif m.type == 'DISTANCE_FROM_OBJECT':
+ elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None:
shaders_list.append(ThicknessDistanceFromObjectShader(
thickness_position, linestyle.thickness_ratio,
m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
@@ -1414,10 +1149,26 @@ def process(layer_name, lineset_name):
thickness_position, linestyle.thickness_ratio,
m.blend, m.influence,
m.orientation, m.thickness_min, m.thickness_max))
+ # -- Textures -- #
+ has_tex = False
+ if scene.render.use_shading_nodes:
+ if linestyle.use_nodes and linestyle.node_tree:
+ shaders_list.append(BlenderTextureShader(linestyle.node_tree))
+ has_tex = True
+ else:
+ if linestyle.use_texture:
+ textures = tuple(BlenderTextureShader(slot) for slot in linestyle.texture_slots if slot is not None)
+ if textures:
+ shaders_list.extend(textures)
+ has_tex = True
+ if has_tex:
+ shaders_list.append(StrokeTextureStepShader(linestyle.texture_spacing))
+ # -- Stroke caps -- #
if linestyle.caps == 'ROUND':
shaders_list.append(RoundCapShader())
elif linestyle.caps == 'SQUARE':
shaders_list.append(SquareCapShader())
+ # -- Dashed line -- #
if linestyle.use_dashed_line:
pattern = []
if linestyle.dash1 > 0 and linestyle.gap1 > 0:
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 99475603bf2..a887ebde449 100644
--- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
@@ -363,6 +363,7 @@ class SpellChecker():
"icosphere",
"inpaint",
"lightmap",
+ "linearlight",
"lossless", "lossy",
"matcap",
"midtones",
@@ -372,6 +373,7 @@ class SpellChecker():
"nurb", "nurbs",
"perlin",
"phong",
+ "pinlight",
"qi",
"radiosity",
"raycasting",
@@ -379,6 +381,7 @@ class SpellChecker():
"renderfarm",
"scanfill",
"shader", "shaders",
+ "softlight",
"specular", "specularity",
"spillmap",
"sobel",
@@ -386,6 +389,7 @@ class SpellChecker():
"tonemap",
"toon",
"timecode",
+ "vividlight",
"voronoi",
"voxel", "voxels",
"vsync",
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index ccc9df93b0d..874efc2e131 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -219,7 +219,10 @@ def resolve_ncase(path):
# we are expecting 'dirpath' to be a directory, but it could be a file
if _os.path.isdir(dirpath):
- files = _os.listdir(dirpath)
+ try:
+ files = _os.listdir(dirpath)
+ except PermissionError: # We might not have the permission to list dirpath...
+ return path, False
else:
return path, False
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 5621af29bc3..b3a7a13e331 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -429,7 +429,7 @@ def time_from_frame(frame, fps=None, fps_base=None):
:arg frame: number.
:type frame: the frame number
:return: the time in seconds.
- :rtype: timedate.timedelta
+ :rtype: datetime.timedelta
"""
if fps is None:
@@ -440,18 +440,18 @@ def time_from_frame(frame, fps=None, fps_base=None):
from datetime import timedelta
- return timedelta((frame * fps_base) / fps)
+ return timedelta(0, (frame * fps_base) / fps)
def time_to_frame(time, fps=None, fps_base=None):
"""
Returns a float frame number from a time given in seconds or
- as a timedate.timedelta object.
+ as a datetime.timedelta object.
If *fps* and *fps_base* are not given the current scene is used.
:arg time: time in seconds.
- :type time: number or a timedate.timedelta object
+ :type time: number or a datetime.timedelta object
:return: the frame.
:rtype: float
"""
diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py
index 1e3e4c873a8..4293930e823 100644
--- a/release/scripts/modules/bpy_extras/mesh_utils.py
+++ b/release/scripts/modules/bpy_extras/mesh_utils.py
@@ -421,7 +421,6 @@ def ngon_tessellate(from_data, indices, fix_loops=True):
loop_segments.append(context_loop)
else:
if context_loop and context_loop[-1][1] == v[1]:
- #raise "as"
pass
else:
context_loop.append(v)
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 766da46107b..01390760c76 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -245,6 +245,7 @@ def object_image_guess(obj, bm=None):
me = obj.data
if bm is None:
if obj.mode == 'EDIT':
+ import bmesh
bm = bmesh.from_edit_mesh(me)
if bm is not None:
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index d2683471915..bc2e9368b71 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -140,6 +140,15 @@ class WindowManager(bpy_types.ID):
finally:
self.pupmenu_end__internal(popup)
+ def popup_menu_pie(self, event, draw_func, title="", icon='NONE'):
+ import bpy
+ pie = self.piemenu_begin__internal(title, icon, event)
+
+ try:
+ draw_func(pie, bpy.context)
+ finally:
+ self.piemenu_end__internal(pie)
+
class _GenericBone:
"""
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index e9c96d59eae..e278b0d20fe 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -57,6 +57,7 @@ def rna_idprop_ui_prop_clear(item, prop):
except:
pass
+
def rna_idprop_context_value(context, context_member, property_type):
space = context.space_data
@@ -73,11 +74,13 @@ def rna_idprop_context_value(context, context_member, property_type):
return rna_item, context_member
+
def rna_idprop_has_properties(rna_item):
keys = rna_item.keys()
nbr_props = len(keys)
return (nbr_props > 1) or (nbr_props and '_RNA_UI' not in keys)
+
def draw(layout, context, context_member, property_type, use_edit=True):
def assign_props(prop, val, key):
diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py
index f87cf611dd4..7fd97c4d347 100644
--- a/release/scripts/modules/sys_info.py
+++ b/release/scripts/modules/sys_info.py
@@ -153,7 +153,8 @@ def write_sysinfo(op):
else:
output.write("\nOpenGL\n")
output.write(lilies)
- output.write("renderer:\t%r\n" % (bgl.glGetString(bgl.GL_RENDERER)))
+ 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)))
output.write("version:\t%r\n" % (bgl.glGetString(bgl.GL_VERSION)))
output.write("extensions:\n")
@@ -163,6 +164,29 @@ def write_sysinfo(op):
for l in glext:
output.write("\t\t%r\n" % (l))
+ output.write("\nImplementation Dependent OpenGL Limits:\n")
+ output.write(lilies)
+ 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])
+
+ output.write("\nGLSL:\n")
+ if version[0] > '1':
+ bgl.glGetIntegerv(bgl.GL_MAX_VARYING_FLOATS, limit)
+ output.write("Maximum Varying Floats:\t%d\n" % limit[0])
+ bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_ATTRIBS, limit)
+ output.write("Maximum Vertex Attributes:\t%d\n" % limit[0])
+ bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_UNIFORM_COMPONENTS, limit)
+ output.write("Maximum Vertex Uniform Components:\t%d\n" % limit[0])
+ bgl.glGetIntegerv(bgl.GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, limit)
+ output.write("Maximum Fragment Uniform Components:\t%d\n" % limit[0])
+ bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, limit)
+ output.write("Maximum Vertex Image Units:\t%d\n" % limit[0])
+ bgl.glGetIntegerv(bgl.GL_MAX_TEXTURE_IMAGE_UNITS, limit)
+ output.write("Maximum Fragment Image Units:\t%d\n" % limit[0])
+ bgl.glGetIntegerv(bgl.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, limit)
+ output.write("Maximum Pipeline Image Units:\t%d\n" % limit[0])
+
output.current_line_index = 0
op.report({'INFO'}, "System information generated in 'system-info.txt'")
diff --git a/release/scripts/presets/camera/1__colon__2.3_inch.py b/release/scripts/presets/camera/1__colon__2.3_inch.py
index 829a060ab35..72548384401 100644
--- a/release/scripts/presets/camera/1__colon__2.3_inch.py
+++ b/release/scripts/presets/camera/1__colon__2.3_inch.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 6.16
-bpy.context.object.data.sensor_height = 4.62
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 6.16
+bpy.context.camera.sensor_height = 4.62
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/1__colon__2.5_inch.py b/release/scripts/presets/camera/1__colon__2.5_inch.py
index 3ddd240ab50..90f60e7d7f0 100644
--- a/release/scripts/presets/camera/1__colon__2.5_inch.py
+++ b/release/scripts/presets/camera/1__colon__2.5_inch.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 5.76
-bpy.context.object.data.sensor_height = 4.29
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 5.76
+bpy.context.camera.sensor_height = 4.29
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/2__colon__3_inch.py b/release/scripts/presets/camera/2__colon__3_inch.py
index edf3bbba2c9..46436970efc 100644
--- a/release/scripts/presets/camera/2__colon__3_inch.py
+++ b/release/scripts/presets/camera/2__colon__3_inch.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 9.6
-bpy.context.object.data.sensor_height = 5.4
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 9.6
+bpy.context.camera.sensor_height = 5.4
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/4__colon__3_inch.py b/release/scripts/presets/camera/4__colon__3_inch.py
index 6e38782c4d8..88346c01ef8 100644
--- a/release/scripts/presets/camera/4__colon__3_inch.py
+++ b/release/scripts/presets/camera/4__colon__3_inch.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 17.31
-bpy.context.object.data.sensor_height = 12.98
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 17.31
+bpy.context.camera.sensor_height = 12.98
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Arri_Alexa.py b/release/scripts/presets/camera/Arri_Alexa.py
index 2bdcf12240b..6a6cdfee12b 100644
--- a/release/scripts/presets/camera/Arri_Alexa.py
+++ b/release/scripts/presets/camera/Arri_Alexa.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 23.760
-bpy.context.object.data.sensor_height = 13.365
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 23.760
+bpy.context.camera.sensor_height = 13.365
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Blackmagic_Cinema_Camera.py b/release/scripts/presets/camera/Blackmagic_Cinema_Camera.py
index 402a5b30cbb..6fde30756da 100644
--- a/release/scripts/presets/camera/Blackmagic_Cinema_Camera.py
+++ b/release/scripts/presets/camera/Blackmagic_Cinema_Camera.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 15.81
-bpy.context.object.data.sensor_height = 8.88
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 15.81
+bpy.context.camera.sensor_height = 8.88
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Blackmagic_Pocket_Cinema_Camera.py b/release/scripts/presets/camera/Blackmagic_Pocket_Cinema_Camera.py
new file mode 100644
index 00000000000..bb2b172919e
--- /dev/null
+++ b/release/scripts/presets/camera/Blackmagic_Pocket_Cinema_Camera.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.camera.sensor_width = 12.48
+bpy.context.camera.sensor_height = 7.02
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Blackmagic_Production_Camera_4K.py b/release/scripts/presets/camera/Blackmagic_Production_Camera_4K.py
new file mode 100644
index 00000000000..dbc12c5aa68
--- /dev/null
+++ b/release/scripts/presets/camera/Blackmagic_Production_Camera_4K.py
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.camera.sensor_width = 21.12
+bpy.context.camera.sensor_height = 11.88
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Blender.py b/release/scripts/presets/camera/Blender.py
index 9fa4ab752e3..ca4906fbb39 100644
--- a/release/scripts/presets/camera/Blender.py
+++ b/release/scripts/presets/camera/Blender.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 32
-bpy.context.object.data.sensor_height = 18
-bpy.context.object.data.sensor_fit = 'AUTO'
+bpy.context.camera.sensor_width = 32
+bpy.context.camera.sensor_height = 18
+bpy.context.camera.sensor_fit = 'AUTO'
diff --git a/release/scripts/presets/camera/Canon_1100D.py b/release/scripts/presets/camera/Canon_1100D.py
index 54f2cf75b54..e665e9e95d5 100644
--- a/release/scripts/presets/camera/Canon_1100D.py
+++ b/release/scripts/presets/camera/Canon_1100D.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 22.2
-bpy.context.object.data.sensor_height = 14.7
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 22.2
+bpy.context.camera.sensor_height = 14.7
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_APS-C.py b/release/scripts/presets/camera/Canon_APS-C.py
index 829e03cc5cf..95108b2187f 100644
--- a/release/scripts/presets/camera/Canon_APS-C.py
+++ b/release/scripts/presets/camera/Canon_APS-C.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 22.3
-bpy.context.object.data.sensor_height = 14.9
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 22.3
+bpy.context.camera.sensor_height = 14.9
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_APS-H.py b/release/scripts/presets/camera/Canon_APS-H.py
index d5cc02f4e4a..d3b61d1aa46 100644
--- a/release/scripts/presets/camera/Canon_APS-H.py
+++ b/release/scripts/presets/camera/Canon_APS-H.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 27.90
-bpy.context.object.data.sensor_height = 18.60
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 27.90
+bpy.context.camera.sensor_height = 18.60
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Canon_C300.py b/release/scripts/presets/camera/Canon_C300.py
index 70c760c73b5..e22af779854 100644
--- a/release/scripts/presets/camera/Canon_C300.py
+++ b/release/scripts/presets/camera/Canon_C300.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 24.4
-bpy.context.object.data.sensor_height = 13.5
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 24.4
+bpy.context.camera.sensor_height = 13.5
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Full_Frame_35mm_Camera.py b/release/scripts/presets/camera/Full_Frame_35mm_Camera.py
index d3e141ba4d9..c8017331b28 100644
--- a/release/scripts/presets/camera/Full_Frame_35mm_Camera.py
+++ b/release/scripts/presets/camera/Full_Frame_35mm_Camera.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 36
-bpy.context.object.data.sensor_height = 24
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 36
+bpy.context.camera.sensor_height = 24
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/GoPro_Hero3_Black.py b/release/scripts/presets/camera/GoPro_Hero3_Black.py
index 9cea698d8ab..e294f802a02 100644
--- a/release/scripts/presets/camera/GoPro_Hero3_Black.py
+++ b/release/scripts/presets/camera/GoPro_Hero3_Black.py
@@ -1,6 +1,6 @@
import bpy
-bpy.context.object.data.sensor_width = 6.16
-bpy.context.object.data.sensor_height = 4.62
-bpy.context.object.data.lens = 2.77
+bpy.context.camera.sensor_width = 6.16
+bpy.context.camera.sensor_height = 4.62
+bpy.context.camera.lens = 2.77
-bpy.context.object.data.sensor_fit = 'AUTO'
+bpy.context.camera.sensor_fit = 'AUTO'
diff --git a/release/scripts/presets/camera/GoPro_Hero3_Silver.py b/release/scripts/presets/camera/GoPro_Hero3_Silver.py
index 1eee0750c2d..247bd7c4aaf 100644
--- a/release/scripts/presets/camera/GoPro_Hero3_Silver.py
+++ b/release/scripts/presets/camera/GoPro_Hero3_Silver.py
@@ -1,6 +1,6 @@
import bpy
-bpy.context.object.data.sensor_width = 5.371
-bpy.context.object.data.sensor_height = 4.035
-bpy.context.object.data.lens = 2.77
+bpy.context.camera.sensor_width = 5.371
+bpy.context.camera.sensor_height = 4.035
+bpy.context.camera.lens = 2.77
-bpy.context.object.data.sensor_fit = 'AUTO'
+bpy.context.camera.sensor_fit = 'AUTO'
diff --git a/release/scripts/presets/camera/GoPro_Hero3_White.py b/release/scripts/presets/camera/GoPro_Hero3_White.py
index 3d1f368aab0..948f838f5d6 100644
--- a/release/scripts/presets/camera/GoPro_Hero3_White.py
+++ b/release/scripts/presets/camera/GoPro_Hero3_White.py
@@ -1,6 +1,6 @@
import bpy
-bpy.context.object.data.sensor_width = 5.76
-bpy.context.object.data.sensor_height = 4.29
-bpy.context.object.data.lens = 2.77
+bpy.context.camera.sensor_width = 5.76
+bpy.context.camera.sensor_height = 4.29
+bpy.context.camera.lens = 2.77
-bpy.context.object.data.sensor_fit = 'AUTO'
+bpy.context.camera.sensor_fit = 'AUTO'
diff --git a/release/scripts/presets/camera/Nexus_5.py b/release/scripts/presets/camera/Nexus_5.py
index aa781782acb..36e741cbba5 100644
--- a/release/scripts/presets/camera/Nexus_5.py
+++ b/release/scripts/presets/camera/Nexus_5.py
@@ -1,5 +1,5 @@
import bpy
-bpy.context.object.data.sensor_width = 4.5
-bpy.context.object.data.sensor_height = 3.37
-bpy.context.object.data.lens = 3.91
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 4.5
+bpy.context.camera.sensor_height = 3.37
+bpy.context.camera.lens = 3.91
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_D3100.py b/release/scripts/presets/camera/Nikon_D3100.py
index 238d9c22d12..b4ceb3aa721 100644
--- a/release/scripts/presets/camera/Nikon_D3100.py
+++ b/release/scripts/presets/camera/Nikon_D3100.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 23.1
-bpy.context.object.data.sensor_height = 15.4
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 23.1
+bpy.context.camera.sensor_height = 15.4
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Nikon_DX.py b/release/scripts/presets/camera/Nikon_DX.py
index a0505bf9b9c..dbe9e7fcc18 100644
--- a/release/scripts/presets/camera/Nikon_DX.py
+++ b/release/scripts/presets/camera/Nikon_DX.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 23.6
-bpy.context.object.data.sensor_height = 15.8
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 23.6
+bpy.context.camera.sensor_height = 15.8
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Panasonic_AG-HVX200.py b/release/scripts/presets/camera/Panasonic_AG-HVX200.py
index ee82cbe9bf0..71ad3c3a161 100644
--- a/release/scripts/presets/camera/Panasonic_AG-HVX200.py
+++ b/release/scripts/presets/camera/Panasonic_AG-HVX200.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 4.68
-bpy.context.object.data.sensor_height = 2.633
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 4.68
+bpy.context.camera.sensor_height = 2.633
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Panasonic_LX2.py b/release/scripts/presets/camera/Panasonic_LX2.py
index 8e0f844e507..d66e02e32d4 100644
--- a/release/scripts/presets/camera/Panasonic_LX2.py
+++ b/release/scripts/presets/camera/Panasonic_LX2.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 8.5
-bpy.context.object.data.sensor_height = 4.78
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 8.5
+bpy.context.camera.sensor_height = 4.78
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Red_Epic.py b/release/scripts/presets/camera/Red_Epic.py
index 14f4abaee90..5d71a69a33d 100644
--- a/release/scripts/presets/camera/Red_Epic.py
+++ b/release/scripts/presets/camera/Red_Epic.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 30.0
-bpy.context.object.data.sensor_height = 15.0
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 30.0
+bpy.context.camera.sensor_height = 15.0
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Red_One_2K.py b/release/scripts/presets/camera/Red_One_2K.py
index ef2708f75b2..894aedcf9ea 100644
--- a/release/scripts/presets/camera/Red_One_2K.py
+++ b/release/scripts/presets/camera/Red_One_2K.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 11.1
-bpy.context.object.data.sensor_height = 6.24
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 11.1
+bpy.context.camera.sensor_height = 6.24
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Red_One_3K.py b/release/scripts/presets/camera/Red_One_3K.py
index 5ddff2746eb..9ac84c1485a 100644
--- a/release/scripts/presets/camera/Red_One_3K.py
+++ b/release/scripts/presets/camera/Red_One_3K.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 16.65
-bpy.context.object.data.sensor_height = 9.36
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 16.65
+bpy.context.camera.sensor_height = 9.36
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Red_One_4K.py b/release/scripts/presets/camera/Red_One_4K.py
index 8ab9b38cbd5..067322cd07e 100644
--- a/release/scripts/presets/camera/Red_One_4K.py
+++ b/release/scripts/presets/camera/Red_One_4K.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 22.2
-bpy.context.object.data.sensor_height = 12.6
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 22.2
+bpy.context.camera.sensor_height = 12.6
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Samsung_Galaxy_S3.py b/release/scripts/presets/camera/Samsung_Galaxy_S3.py
index 35670042e48..23eaea7cd27 100644
--- a/release/scripts/presets/camera/Samsung_Galaxy_S3.py
+++ b/release/scripts/presets/camera/Samsung_Galaxy_S3.py
@@ -1,5 +1,5 @@
import bpy
-bpy.context.object.data.sensor_width = 4.8
-bpy.context.object.data.sensor_height = 3.6
-bpy.context.object.data.lens = 3.70
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 4.8
+bpy.context.camera.sensor_height = 3.6
+bpy.context.camera.lens = 3.70
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Samsung_Galaxy_S4.py b/release/scripts/presets/camera/Samsung_Galaxy_S4.py
index ae16d4172f9..cc929d26dac 100644
--- a/release/scripts/presets/camera/Samsung_Galaxy_S4.py
+++ b/release/scripts/presets/camera/Samsung_Galaxy_S4.py
@@ -1,5 +1,5 @@
import bpy
-bpy.context.object.data.sensor_width = 4.8
-bpy.context.object.data.sensor_height = 3.6
-bpy.context.object.data.lens = 4.20
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 4.8
+bpy.context.camera.sensor_height = 3.6
+bpy.context.camera.lens = 4.20
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Sony_A55.py b/release/scripts/presets/camera/Sony_A55.py
index b0f172206fa..0468deb6d4c 100644
--- a/release/scripts/presets/camera/Sony_A55.py
+++ b/release/scripts/presets/camera/Sony_A55.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 23.4
-bpy.context.object.data.sensor_height = 15.6
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 23.4
+bpy.context.camera.sensor_height = 15.6
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Sony_EX1.py b/release/scripts/presets/camera/Sony_EX1.py
index 00708175b40..3c6b235f21e 100644
--- a/release/scripts/presets/camera/Sony_EX1.py
+++ b/release/scripts/presets/camera/Sony_EX1.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 6.97
-bpy.context.object.data.sensor_height = 3.92
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 6.97
+bpy.context.camera.sensor_height = 3.92
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Sony_F65.py b/release/scripts/presets/camera/Sony_F65.py
index e187828058b..e62b3511836 100644
--- a/release/scripts/presets/camera/Sony_F65.py
+++ b/release/scripts/presets/camera/Sony_F65.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 24.33
-bpy.context.object.data.sensor_height = 12.83
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 24.33
+bpy.context.camera.sensor_height = 12.83
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Super_16_Film.py b/release/scripts/presets/camera/Super_16_Film.py
index 1e42953bf05..4ca397a7e27 100644
--- a/release/scripts/presets/camera/Super_16_Film.py
+++ b/release/scripts/presets/camera/Super_16_Film.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 12.52
-bpy.context.object.data.sensor_height = 7.41
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 12.52
+bpy.context.camera.sensor_height = 7.41
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/Super_35_Film.py b/release/scripts/presets/camera/Super_35_Film.py
index 65ccb0f216c..b22ff545c68 100644
--- a/release/scripts/presets/camera/Super_35_Film.py
+++ b/release/scripts/presets/camera/Super_35_Film.py
@@ -1,4 +1,4 @@
import bpy
-bpy.context.object.data.sensor_width = 24.89
-bpy.context.object.data.sensor_height = 18.66
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 24.89
+bpy.context.camera.sensor_height = 18.66
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/iPhone_4.py b/release/scripts/presets/camera/iPhone_4.py
index b87dda18097..1e43cd11494 100644
--- a/release/scripts/presets/camera/iPhone_4.py
+++ b/release/scripts/presets/camera/iPhone_4.py
@@ -1,5 +1,5 @@
import bpy
-bpy.context.object.data.sensor_width = 4.54
-bpy.context.object.data.sensor_height = 3.42
-bpy.context.object.data.lens = 3.85
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 4.54
+bpy.context.camera.sensor_height = 3.42
+bpy.context.camera.lens = 3.85
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/iPhone_4S.py b/release/scripts/presets/camera/iPhone_4S.py
index ea747f339d4..1139b7395b5 100644
--- a/release/scripts/presets/camera/iPhone_4S.py
+++ b/release/scripts/presets/camera/iPhone_4S.py
@@ -1,5 +1,5 @@
import bpy
-bpy.context.object.data.sensor_width = 4.54
-bpy.context.object.data.sensor_height = 3.42
-bpy.context.object.data.lens = 4.28
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 4.54
+bpy.context.camera.sensor_height = 3.42
+bpy.context.camera.lens = 4.28
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/camera/iPhone_5.py b/release/scripts/presets/camera/iPhone_5.py
index 2764788a405..a6b6bbc2ec5 100644
--- a/release/scripts/presets/camera/iPhone_5.py
+++ b/release/scripts/presets/camera/iPhone_5.py
@@ -1,5 +1,5 @@
import bpy
-bpy.context.object.data.sensor_width = 4.54
-bpy.context.object.data.sensor_height = 3.42
-bpy.context.object.data.lens = 4.10
-bpy.context.object.data.sensor_fit = 'HORIZONTAL'
+bpy.context.camera.sensor_width = 4.54
+bpy.context.camera.sensor_height = 3.42
+bpy.context.camera.lens = 4.10
+bpy.context.camera.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/cycles/integrator/direct_light.py b/release/scripts/presets/cycles/integrator/direct_light.py
index 504068722d7..12b332cb431 100644
--- a/release/scripts/presets/cycles/integrator/direct_light.py
+++ b/release/scripts/presets/cycles/integrator/direct_light.py
@@ -3,9 +3,11 @@ cycles = bpy.context.scene.cycles
cycles.max_bounces = 8
cycles.min_bounces = 8
-cycles.no_caustics = True
+cycles.caustics_reflective = False
+cycles.caustics_refractive = False
cycles.diffuse_bounces = 0
cycles.glossy_bounces = 1
cycles.transmission_bounces = 2
+cycles.volume_bounces = 0
cycles.transparent_min_bounces = 8
cycles.transparent_max_bounces = 8
diff --git a/release/scripts/presets/cycles/integrator/full_global_illumination.py b/release/scripts/presets/cycles/integrator/full_global_illumination.py
index 8687f169b8a..69fa6e735bd 100644
--- a/release/scripts/presets/cycles/integrator/full_global_illumination.py
+++ b/release/scripts/presets/cycles/integrator/full_global_illumination.py
@@ -3,9 +3,11 @@ cycles = bpy.context.scene.cycles
cycles.max_bounces = 128
cycles.min_bounces = 3
-cycles.no_caustics = False
+cycles.caustics_reflective = True
+cycles.caustics_refractive = True
cycles.diffuse_bounces = 128
cycles.glossy_bounces = 128
cycles.transmission_bounces = 128
+cycles.volume_bounces = 128
cycles.transparent_min_bounces = 8
cycles.transparent_max_bounces = 128
diff --git a/release/scripts/presets/cycles/integrator/limited_global_illumination.py b/release/scripts/presets/cycles/integrator/limited_global_illumination.py
index f2a7e1f7b7a..22a8478d23b 100644
--- a/release/scripts/presets/cycles/integrator/limited_global_illumination.py
+++ b/release/scripts/presets/cycles/integrator/limited_global_illumination.py
@@ -3,9 +3,11 @@ cycles = bpy.context.scene.cycles
cycles.max_bounces = 8
cycles.min_bounces = 3
-cycles.no_caustics = True
+cycles.caustics_reflective = False
+cycles.caustics_refractive = False
cycles.diffuse_bounces = 1
cycles.glossy_bounces = 4
cycles.transmission_bounces = 8
+cycles.volume_bounces = 2
cycles.transparent_min_bounces = 8
cycles.transparent_max_bounces = 8
diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml
index b9e84e1eb7e..152e944a7ba 100644
--- a/release/scripts/presets/interface_theme/back_to_black.xml
+++ b/release/scripts/presets/interface_theme/back_to_black.xml
@@ -152,6 +152,18 @@
shadedown="0">
</ThemeWidgetColors>
</wcol_menu_back>
+ <wcol_pie_menu>
+ <ThemeWidgetColors outline="#0a0a0a"
+ inner="#191919e6"
+ inner_sel="#8c8c8cff"
+ item="#2d2d2de6"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_pie_menu>
<wcol_tooltip>
<ThemeWidgetColors outline="#000000"
inner="#191919e6"
@@ -231,6 +243,7 @@
lamp="#c1d40028"
speaker="#535353"
camera="#000000"
+ view_overlay="#000000"
empty="#000000"
object_selected="#f15800"
object_active="#ff8c19"
@@ -260,10 +273,10 @@
handle_free="#7f7f7f"
handle_auto="#909000"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#803060"
handle_sel_free="#3b3b3b"
handle_sel_auto="#f0ff40"
- handle_sel_vect="#40c030"
handle_sel_align="#f090a0"
lastsel_point="#ffffff"
extra_edge_len="#ffedf8"
@@ -280,7 +293,9 @@
outline_width="1"
bundle_solid="#c8c8c8"
camera_path="#5a5a5a"
- skin_root="#000000">
+ skin_root="#000000"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGradient title="#5d5d5d"
text="#7d7d7d"
@@ -292,13 +307,13 @@
button_title="#c5c5c5"
button_text="#c3c3c3"
button_text_hi="#ffffff"
- tab_active="#000000"
+ tab_active="#212947"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<gradients>
- <ThemeGradientColors show_grad="FALSE"
- gradient="#393939"
+ <ThemeGradientColors show_grad="TRUE"
+ gradient="#0a0a0a"
high_gradient="#000000">
</ThemeGradientColors>
</gradients>
@@ -329,10 +344,10 @@
handle_free="#808080"
handle_auto="#909000"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#803060"
handle_sel_free="#808080"
handle_sel_auto="#f0ff40"
- handle_sel_vect="#40c030"
handle_sel_align="#f090a0"
handle_auto_clamped="#994030"
handle_sel_auto_clamped="#f0af90"
@@ -354,7 +369,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -394,7 +409,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -417,21 +432,21 @@
<nla_editor>
<ThemeNLAEditor grid="#5e5e5e"
view_sliders="#969696"
- active_action="#00000000"
- active_action_unset="#00000000"
- strips="#aa8d8d"
+ active_action="#cc701a66"
+ active_action_unset="#9987614d"
+ strips="#0c0a0a"
strips_selected="#ff8c00"
- transition_strips="#000000"
- transition_strips_selected="#000000"
- meta_strips="#000000"
- meta_strips_selected="#000000"
- sound_strips="#000000"
- sound_strips_selected="#000000"
- tweak="#000000"
- tweak_duplicate="#000000"
+ transition_strips="#1c2630"
+ transition_strips_selected="#2e75db"
+ meta_strips="#332642"
+ meta_strips_selected="#692196"
+ sound_strips="#2b3d3d"
+ sound_strips_selected="#1f7a7a"
+ tweak="#4df31a"
+ tweak_duplicate="#d90000"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
- frame_current="#2f6421">
+ frame_current="#60c040">
<space>
<ThemeSpaceGeneric back="#0d0d0d"
title="#585858"
@@ -446,7 +461,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -504,7 +519,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -545,7 +560,21 @@
preview_stitch_unstitchable="#ff0000ff"
preview_stitch_active="#e1d2c323"
uv_shadow="#707070ff"
- uv_others="#606060ff">
+ uv_others="#606060ff"
+ frame_current="#60c040"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGeneric back="#000000"
title="#5d5d5d"
@@ -560,7 +589,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -602,7 +631,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -631,7 +660,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -670,7 +699,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -700,7 +729,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -751,7 +780,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -787,7 +816,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -817,7 +846,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -855,7 +884,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -884,7 +913,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -918,7 +947,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -942,11 +971,19 @@
path_after="#0000ff"
grid="#5e5e5e"
frame_current="#1b501b"
- handle_vertex="#e2e2e2"
- handle_vertex_select="#ffff00"
- handle_vertex_size="4"
strips="#0c0a0a"
- strips_selected="#ff8c00">
+ strips_selected="#ff8c00"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5">
<space>
<ThemeSpaceGeneric back="#0d0d0d"
title="#5d5d5d"
@@ -961,7 +998,7 @@
button_text_hi="#ffffff"
tab_active="#000000"
tab_inactive="#000000"
- tab_back="#060606"
+ tab_back="#060606ff"
tab_outline="#3a3a3a">
<panelcolors>
<ThemePanelColors header="#00000019"
diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml
index f11a26f9700..9cb3276b103 100644
--- a/release/scripts/presets/interface_theme/blender_24x.xml
+++ b/release/scripts/presets/interface_theme/blender_24x.xml
@@ -152,6 +152,18 @@
shadedown="25">
</ThemeWidgetColors>
</wcol_menu_back>
+ <wcol_pie_menu>
+ <ThemeWidgetColors outline="#0a0a0a"
+ inner="#191919e6"
+ inner_sel="#8c8c8cff"
+ item="#2d2d2de6"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_pie_menu>
<wcol_tooltip>
<ThemeWidgetColors outline="#000000"
inner="#ffffddff"
@@ -231,6 +243,7 @@
lamp="#00000028"
speaker="#000000"
camera="#000000"
+ view_overlay="#000000"
empty="#000000"
object_selected="#ff88ff"
object_active="#ffbbff"
@@ -260,10 +273,10 @@
handle_free="#000000"
handle_auto="#909000"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#803060"
handle_sel_free="#000000"
handle_sel_auto="#f0ff40"
- handle_sel_vect="#40c030"
handle_sel_align="#f090a0"
lastsel_point="#ffffff"
extra_edge_len="#200000"
@@ -280,7 +293,9 @@
outline_width="1"
bundle_solid="#c8c8c8"
camera_path="#000000"
- skin_root="#000000">
+ skin_root="#000000"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGradient title="#000000"
text="#000000"
@@ -294,7 +309,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<gradients>
<ThemeGradientColors show_grad="FALSE"
@@ -329,10 +344,10 @@
handle_free="#000000"
handle_auto="#909000"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#803060"
handle_sel_free="#000000"
handle_sel_auto="#f0ff40"
- handle_sel_vect="#40c030"
handle_sel_align="#f090a0"
handle_auto_clamped="#000000"
handle_sel_auto_clamped="#000000"
@@ -354,7 +369,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -394,7 +409,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -446,7 +461,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -504,7 +519,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -545,7 +560,21 @@
preview_stitch_unstitchable="#ff0000ff"
preview_stitch_active="#e1d2c323"
uv_shadow="#707070ff"
- uv_others="#606060ff">
+ uv_others="#606060ff"
+ frame_current="#60c040"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGeneric back="#353535"
title="#000000"
@@ -560,7 +589,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -602,7 +631,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -631,7 +660,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -670,7 +699,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -700,7 +729,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -751,7 +780,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -787,7 +816,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -817,7 +846,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -855,7 +884,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -884,7 +913,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -918,7 +947,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -942,11 +971,19 @@
path_after="#0000ff"
grid="#5e5e5e"
frame_current="#60c040"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
handle_vertex="#000000"
handle_vertex_select="#ffff00"
- handle_vertex_size="4"
- strips="#0c0a0a"
- strips_selected="#ff8c00">
+ handle_vertex_size="4">
<space>
<ThemeSpaceGeneric back="#757575"
title="#000000"
@@ -961,7 +998,7 @@
button_text_hi="#ffffff"
tab_active="#b4b4b4"
tab_inactive="#999999"
- tab_back="#757575"
+ tab_back="#757575ff"
tab_outline="#3c3c3c">
<panelcolors>
<ThemePanelColors header="#00000019"
diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml
index 3fef9486d9e..2d213d0ed70 100644
--- a/release/scripts/presets/interface_theme/elsyiun.xml
+++ b/release/scripts/presets/interface_theme/elsyiun.xml
@@ -152,6 +152,18 @@
shadedown="-20">
</ThemeWidgetColors>
</wcol_menu_back>
+ <wcol_pie_menu>
+ <ThemeWidgetColors outline="#0a0a0a"
+ inner="#191919e6"
+ inner_sel="#8c8c8cff"
+ item="#2d2d2de6"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_pie_menu>
<wcol_tooltip>
<ThemeWidgetColors outline="#000000"
inner="#191919e6"
@@ -231,6 +243,7 @@
lamp="#00000028"
speaker="#000000"
camera="#000000"
+ view_overlay="#000000"
empty="#000000"
object_selected="#ff8500"
object_active="#ffc280"
@@ -260,10 +273,10 @@
handle_free="#000000"
handle_auto="#909000"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#803060"
handle_sel_free="#000000"
handle_sel_auto="#f0ff40"
- handle_sel_vect="#40c030"
handle_sel_align="#f090a0"
lastsel_point="#ffffff"
extra_edge_len="#200000"
@@ -280,7 +293,9 @@
outline_width="1"
bundle_solid="#c8c8c8"
camera_path="#000000"
- skin_root="#000000">
+ skin_root="#000000"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGradient title="#000000"
text="#b8b8b8"
@@ -294,7 +309,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<gradients>
<ThemeGradientColors show_grad="FALSE"
@@ -329,10 +344,10 @@
handle_free="#000000"
handle_auto="#909000"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#803060"
handle_sel_free="#000000"
handle_sel_auto="#f0ff40"
- handle_sel_vect="#40c030"
handle_sel_align="#f090a0"
handle_auto_clamped="#994030"
handle_sel_auto_clamped="#f0af90"
@@ -354,7 +369,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -394,7 +409,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -446,7 +461,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -504,7 +519,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -545,7 +560,21 @@
preview_stitch_unstitchable="#ff0000ff"
preview_stitch_active="#e1d2c323"
uv_shadow="#707070ff"
- uv_others="#606060ff">
+ uv_others="#606060ff"
+ frame_current="#60c040"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGeneric back="#4b4b4b"
title="#8b8b8b"
@@ -560,7 +589,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -602,7 +631,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -631,7 +660,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -670,7 +699,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -700,7 +729,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -751,7 +780,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -787,7 +816,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -817,7 +846,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -855,7 +884,7 @@
button_text_hi="#000000"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -884,7 +913,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -918,7 +947,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -942,11 +971,19 @@
path_after="#0000ff"
grid="#5e5e5e"
frame_current="#60c040"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
handle_vertex="#000000"
handle_vertex_select="#ffff00"
- handle_vertex_size="4"
- strips="#0c0a0a"
- strips_selected="#ff8c00">
+ handle_vertex_size="4">
<space>
<ThemeSpaceGeneric back="#393939"
title="#000000"
@@ -961,7 +998,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml
index d32bd81b6f6..d2221bc9935 100644
--- a/release/scripts/presets/interface_theme/hexagon.xml
+++ b/release/scripts/presets/interface_theme/hexagon.xml
@@ -152,6 +152,18 @@
shadedown="-40">
</ThemeWidgetColors>
</wcol_menu_back>
+ <wcol_pie_menu>
+ <ThemeWidgetColors outline="#0a0a0a"
+ inner="#191919e6"
+ inner_sel="#8c8c8cff"
+ item="#2d2d2de6"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_pie_menu>
<wcol_tooltip>
<ThemeWidgetColors outline="#000000"
inner="#191919e6"
@@ -231,6 +243,7 @@
lamp="#00000028"
speaker="#000000"
camera="#000000"
+ view_overlay="#000000"
empty="#000000"
object_selected="#52c6ff"
object_active="#6ed8ff"
@@ -260,10 +273,10 @@
handle_free="#000000"
handle_auto="#909000"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#803060"
handle_sel_free="#000000"
handle_sel_auto="#f0ff40"
- handle_sel_vect="#40c030"
handle_sel_align="#f090a0"
lastsel_point="#ffffff"
extra_edge_len="#200000"
@@ -280,7 +293,9 @@
outline_width="1"
bundle_solid="#c8c8c8"
camera_path="#000000"
- skin_root="#000000">
+ skin_root="#000000"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGradient title="#000000"
text="#000000"
@@ -294,7 +309,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<gradients>
<ThemeGradientColors show_grad="FALSE"
@@ -329,10 +344,10 @@
handle_free="#000000"
handle_auto="#909000"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#803060"
handle_sel_free="#000000"
handle_sel_auto="#f0ff40"
- handle_sel_vect="#40c030"
handle_sel_align="#f090a0"
handle_auto_clamped="#000000"
handle_sel_auto_clamped="#000000"
@@ -354,7 +369,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -394,7 +409,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -446,7 +461,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -504,7 +519,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -545,7 +560,21 @@
preview_stitch_unstitchable="#ff0000ff"
preview_stitch_active="#e1d2c323"
uv_shadow="#707070ff"
- uv_others="#606060ff">
+ uv_others="#606060ff"
+ frame_current="#60c040"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGeneric back="#7c7e88"
title="#000000"
@@ -560,7 +589,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -602,7 +631,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -631,7 +660,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#404040"
+ tab_back="#404040ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -670,7 +699,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -700,7 +729,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -751,7 +780,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -787,7 +816,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -817,7 +846,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -855,7 +884,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -884,7 +913,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -918,7 +947,7 @@
button_text_hi="#ffffff"
tab_active="#464646"
tab_inactive="#393939"
- tab_back="#000000"
+ tab_back="#000000ff"
tab_outline="#323232">
<panelcolors>
<ThemePanelColors header="#00000019"
@@ -942,11 +971,19 @@
path_after="#0000ff"
grid="#5e5e5e"
frame_current="#60c040"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
handle_vertex="#000000"
handle_vertex_select="#ffff00"
- handle_vertex_size="4"
- strips="#0c0a0a"
- strips_selected="#ff8c00">
+ handle_vertex_size="4">
<space>
<ThemeSpaceGeneric back="#7c7e88"
title="#000000"
@@ -961,7 +998,7 @@
button_text_hi="#ffffff"
tab_active="#6c717f"
tab_inactive="#565b65"
- tab_back="#4b5058"
+ tab_back="#4b5058ff"
tab_outline="#2d2d32">
<panelcolors>
<ThemePanelColors header="#00000019"
diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
index 9de72b93bcf..06d29a97745 100644
--- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
+++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
@@ -152,6 +152,18 @@
shadedown="-20">
</ThemeWidgetColors>
</wcol_menu_back>
+ <wcol_pie_menu>
+ <ThemeWidgetColors outline="#0a0a0a"
+ inner="#191919e6"
+ inner_sel="#8c8c8cff"
+ item="#2d2d2de6"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_pie_menu>
<wcol_tooltip>
<ThemeWidgetColors outline="#000000"
inner="#191919e6"
@@ -231,6 +243,7 @@
lamp="#ffffff34"
speaker="#93237f"
camera="#159dce"
+ view_overlay="#000000"
empty="#93237f"
object_selected="#f15800"
object_active="#f47421"
@@ -260,10 +273,10 @@
handle_free="#a5ca00"
handle_auto="#00c59a"
handle_vect="#409030"
+ handle_sel_vect="#82c036"
handle_align="#93237f"
handle_sel_free="#f47421"
handle_sel_auto="#f47421"
- handle_sel_vect="#82c036"
handle_sel_align="#f47421"
lastsel_point="#ffffff"
extra_edge_len="#200000"
@@ -280,7 +293,9 @@
outline_width="2"
bundle_solid="#c8c8c8"
camera_path="#7dbd00"
- skin_root="#000000">
+ skin_root="#000000"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGradient title="#9c9c9c"
text="#9c9c9c"
@@ -294,7 +309,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<gradients>
<ThemeGradientColors show_grad="FALSE"
@@ -329,10 +344,10 @@
handle_free="#a5ca00"
handle_auto="#00c59a"
handle_vect="#409030"
+ handle_sel_vect="#40c030"
handle_align="#93237f"
handle_sel_free="#f49600"
handle_sel_auto="#f49600"
- handle_sel_vect="#40c030"
handle_sel_align="#f49600"
handle_auto_clamped="#03aa60"
handle_sel_auto_clamped="#f49600"
@@ -354,7 +369,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -394,7 +409,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -446,7 +461,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -504,7 +519,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -545,7 +560,21 @@
preview_stitch_unstitchable="#ff0000ff"
preview_stitch_active="#e1d2c323"
uv_shadow="#707070ff"
- uv_others="#606060ff">
+ uv_others="#606060ff"
+ frame_current="#60c040"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
<space>
<ThemeSpaceGeneric back="#131311"
title="#000000"
@@ -560,7 +589,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -602,7 +631,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -631,7 +660,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -670,7 +699,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -700,7 +729,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -751,7 +780,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -787,7 +816,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -817,7 +846,7 @@
button_text_hi="#f47421"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -855,7 +884,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -884,7 +913,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -918,7 +947,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
@@ -942,11 +971,19 @@
path_after="#19b6ee"
grid="#302e2c"
frame_current="#f47421"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
handle_vertex="#000000"
handle_vertex_select="#ffff00"
- handle_vertex_size="4"
- strips="#0c0a0a"
- strips_selected="#ff8c00">
+ handle_vertex_size="4">
<space>
<ThemeSpaceGeneric back="#131311"
title="#9c9c9c"
@@ -961,7 +998,7 @@
button_text_hi="#ffffff"
tab_active="#3c3b37"
tab_inactive="#333333"
- tab_back="#2e2e2e"
+ tab_back="#2e2e2eff"
tab_outline="#000000">
<panelcolors>
<ThemePanelColors header="#00000000"
diff --git a/release/scripts/presets/keyconfig/3dsmax.py b/release/scripts/presets/keyconfig/3dsmax.py
index 808ba7cee81..f85d3b43041 100644
--- a/release/scripts/presets/keyconfig/3dsmax.py
+++ b/release/scripts/presets/keyconfig/3dsmax.py
@@ -14,8 +14,8 @@ kmi = km.keymap_items.new('wm.call_menu', 'O', 'PRESS', shift=True, ctrl=True)
kmi.properties.name = 'INFO_MT_file_open_recent'
kmi = km.keymap_items.new('wm.open_mainfile', 'O', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.open_mainfile', 'F1', 'PRESS')
-kmi = km.keymap_items.new('wm.link_append', 'O', 'PRESS', ctrl=True, alt=True)
-kmi = km.keymap_items.new('wm.link_append', 'F1', 'PRESS', shift=True)
+kmi = km.keymap_items.new('wm.link', 'O', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('wm.append', 'F1', 'PRESS', shift=True)
kmi.properties.link = False
kmi.properties.instance_groups = False
kmi = km.keymap_items.new('wm.save_mainfile', 'S', 'PRESS', ctrl=True)
@@ -295,8 +295,6 @@ kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
kmi = km.keymap_items.new('wm.context_toggle', 'O', 'PRESS')
kmi.properties.data_path = 'tool_settings.use_proportional_edit_objects'
kmi = km.keymap_items.new('view3d.game_start', 'P', 'PRESS', shift=True, ctrl=True, alt=True)
-kmi = km.keymap_items.new('object.select_all', 'LEFTMOUSE', 'CLICK')
-kmi.properties.action = 'DESELECT'
kmi = km.keymap_items.new('object.select_all', 'A', 'PRESS', ctrl=True)
kmi.properties.action = 'INVERT'
kmi = km.keymap_items.new('object.select_linked', 'L', 'PRESS', shift=True)
@@ -588,56 +586,56 @@ kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True)
kmi.properties.data_path = 'space_data.viewport_shade'
kmi.properties.value_1 = 'SOLID'
kmi.properties.value_2 = 'TEXTURED'
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE')
+kmi = km.keymap_items.new('view3d.select_or_deselect_all', 'SELECTMOUSE', 'CLICK')
kmi.properties.extend = False
kmi.properties.deselect = False
kmi.properties.toggle = False
kmi.properties.center = False
kmi.properties.enumerate = False
kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True)
+kmi = km.keymap_items.new('view3d.select_or_deselect_all', 'SELECTMOUSE', 'CLICK', ctrl=True)
kmi.properties.extend = False
kmi.properties.deselect = False
kmi.properties.toggle = True
kmi.properties.center = False
kmi.properties.enumerate = False
kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True)
+kmi = km.keymap_items.new('view3d.select_or_deselect_all', 'SELECTMOUSE', 'CLICK', shift=True)
kmi.properties.extend = False
kmi.properties.deselect = False
kmi.properties.toggle = False
kmi.properties.center = True
kmi.properties.enumerate = False
kmi.properties.object = True
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', alt=True)
+kmi = km.keymap_items.new('view3d.select_or_deselect_all', 'SELECTMOUSE', 'CLICK', alt=True)
kmi.properties.extend = False
kmi.properties.deselect = False
kmi.properties.toggle = False
kmi.properties.center = False
kmi.properties.enumerate = True
kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True)
+kmi = km.keymap_items.new('view3d.select_or_deselect_all', 'SELECTMOUSE', 'CLICK', shift=True, ctrl=True)
kmi.properties.extend = True
kmi.properties.deselect = False
kmi.properties.toggle = True
kmi.properties.center = True
kmi.properties.enumerate = False
kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True, alt=True)
+kmi = km.keymap_items.new('view3d.select_or_deselect_all', 'SELECTMOUSE', 'CLICK', ctrl=True, alt=True)
kmi.properties.extend = False
kmi.properties.deselect = False
kmi.properties.toggle = False
kmi.properties.center = True
kmi.properties.enumerate = True
kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, alt=True)
+kmi = km.keymap_items.new('view3d.select_or_deselect_all', 'SELECTMOUSE', 'CLICK', shift=True, alt=True)
kmi.properties.extend = False
kmi.properties.deselect = False
kmi.properties.toggle = True
kmi.properties.center = False
kmi.properties.enumerate = True
kmi.properties.object = False
-kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True, alt=True)
+kmi = km.keymap_items.new('view3d.select_or_deselect_all', 'SELECTMOUSE', 'CLICK', shift=True, ctrl=True, alt=True)
kmi.properties.extend = False
kmi.properties.deselect = False
kmi.properties.toggle = True
@@ -1076,7 +1074,7 @@ kmi = km.keymap_items.new('node.select_all', 'I', 'PRESS', ctrl=True)
kmi.properties.action = 'INVERT'
kmi = km.keymap_items.new('node.select_linked_to', 'L', 'PRESS', shift=True)
kmi = km.keymap_items.new('node.select_linked_from', 'L', 'PRESS')
-kmi = km.keymap_items.new('node.select_same_type', 'G', 'PRESS', shift=True)
+kmi = km.keymap_items.new('node.select_grouped', 'G', 'PRESS', shift=True)
kmi = km.keymap_items.new('node.select_same_type_step', 'RIGHT_BRACKET', 'PRESS', shift=True)
kmi.properties.prev = False
kmi = km.keymap_items.new('node.select_same_type_step', 'LEFT_BRACKET', 'PRESS', shift=True)
@@ -1389,32 +1387,32 @@ kmi.properties.camera = 10
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS')
kmi.properties.extend = False
kmi.properties.linked_handle = False
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = False
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS', shift=True)
kmi.properties.extend = True
kmi.properties.linked_handle = False
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = False
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS', alt=True)
kmi.properties.extend = False
kmi.properties.linked_handle = True
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = False
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
kmi.properties.extend = True
kmi.properties.linked_handle = True
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = False
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS', ctrl=True)
kmi.properties.extend = False
kmi.properties.linked_handle = False
-kmi.properties.left_right = True
+kmi.properties.left_right = 'MOUSE'
kmi.properties.linked_time = True
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True)
kmi.properties.extend = True
kmi.properties.linked_handle = False
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = True
kmi = km.keymap_items.new('sequencer.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('sequencer.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
@@ -2112,8 +2110,6 @@ kmi.properties.extend = False
kmi.properties.deselect = False
kmi.properties.toggle = True
kmi = km.keymap_items.new('mesh.shortest_path_pick', 'SELECTMOUSE', 'PRESS', ctrl=True)
-kmi = km.keymap_items.new('mesh.select_all', 'LEFTMOUSE', 'CLICK')
-kmi.properties.action = 'DESELECT'
kmi = km.keymap_items.new('mesh.select_all', 'I', 'PRESS', ctrl=True)
kmi.properties.action = 'INVERT'
kmi = km.keymap_items.new('mesh.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py
index da10b17422e..436541d85f8 100644
--- a/release/scripts/presets/keyconfig/maya.py
+++ b/release/scripts/presets/keyconfig/maya.py
@@ -15,8 +15,8 @@ kmi = km.keymap_items.new('wm.call_menu', 'O', 'PRESS', shift=True, ctrl=True)
kmi.properties.name = 'INFO_MT_file_open_recent'
kmi = km.keymap_items.new('wm.open_mainfile', 'O', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.open_mainfile', 'F1', 'PRESS')
-kmi = km.keymap_items.new('wm.link_append', 'O', 'PRESS', ctrl=True, alt=True)
-kmi = km.keymap_items.new('wm.link_append', 'F1', 'PRESS', shift=True)
+kmi = km.keymap_items.new('wm.link', 'O', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('wm.append', 'F1', 'PRESS', shift=True)
kmi.properties.link = False
kmi.properties.instance_groups = False
kmi = km.keymap_items.new('wm.save_mainfile', 'S', 'PRESS', ctrl=True)
@@ -329,6 +329,7 @@ kmi = km.keymap_items.new('armature.layers_show_all', 'ACCENT_GRAVE', 'PRESS', c
kmi = km.keymap_items.new('armature.armature_layers', 'M', 'PRESS', shift=True)
kmi = km.keymap_items.new('pose.bone_layers', 'M', 'PRESS')
kmi = km.keymap_items.new('transform.transform', 'S', 'PRESS', ctrl=True, alt=True)
+kmi.properties.mode = 'BONE_SIZE'
kmi = km.keymap_items.new('anim.keyframe_insert_menu', 'S', 'PRESS')
kmi = km.keymap_items.new('anim.keyframe_delete_v3d', 'S', 'PRESS', alt=True)
kmi = km.keymap_items.new('anim.keying_set_active_set', 'I', 'PRESS', shift=True, ctrl=True, alt=True)
@@ -1486,7 +1487,7 @@ kmi = km.keymap_items.new('node.delete_reconnect', 'X', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('node.select_all', 'A', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('node.select_linked_to', 'L', 'PRESS', shift=True)
kmi = km.keymap_items.new('node.select_linked_from', 'L', 'PRESS')
-kmi = km.keymap_items.new('node.select_same_type', 'G', 'PRESS', shift=True)
+kmi = km.keymap_items.new('node.select_grouped', 'G', 'PRESS', shift=True)
kmi = km.keymap_items.new('node.select_same_type_step', 'RIGHT_BRACKET', 'PRESS', shift=True)
kmi.properties.prev = True
kmi = km.keymap_items.new('node.select_same_type_step', 'LEFT_BRACKET', 'PRESS', shift=True)
@@ -1745,32 +1746,32 @@ kmi.properties.camera = 10
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'CLICK')
kmi.properties.extend = False
kmi.properties.linked_handle = False
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = False
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'CLICK', shift=True)
kmi.properties.extend = True
kmi.properties.linked_handle = False
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = False
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS', alt=True)
kmi.properties.extend = False
kmi.properties.linked_handle = True
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = False
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'CLICK', shift=True, alt=True)
kmi.properties.extend = True
kmi.properties.linked_handle = True
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = False
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS', ctrl=True)
kmi.properties.extend = False
kmi.properties.linked_handle = False
-kmi.properties.left_right = True
+kmi.properties.left_right = 'MOUSE'
kmi.properties.linked_time = True
kmi = km.keymap_items.new('sequencer.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True)
kmi.properties.extend = True
kmi.properties.linked_handle = False
-kmi.properties.left_right = False
+kmi.properties.left_right = 'NONE'
kmi.properties.linked_time = True
kmi = km.keymap_items.new('sequencer.select_more', 'PERIOD', 'PRESS', shift=True)
kmi = km.keymap_items.new('sequencer.select_less', 'COMMA', 'PRESS', shift=True)
diff --git a/release/scripts/presets/sunsky/classic.py b/release/scripts/presets/sunsky/classic.py
index 4394dcce242..edb065d553c 100644
--- a/release/scripts/presets/sunsky/classic.py
+++ b/release/scripts/presets/sunsky/classic.py
@@ -1,14 +1,14 @@
import bpy
-bpy.context.object.data.sky.atmosphere_turbidity = 4.0
-bpy.context.object.data.sky.sky_blend_type = 'ADD'
-bpy.context.object.data.sky.sky_blend = 1.0
-bpy.context.object.data.sky.horizon_brightness = 10.0
-bpy.context.object.data.sky.spread = 1.49011614159e-09
-bpy.context.object.data.sky.sky_color_space = 'SMPTE'
-bpy.context.object.data.sky.sky_exposure = 1.0
-bpy.context.object.data.sky.sun_brightness = 1.00000011921
-bpy.context.object.data.sky.sun_size = 1.00000166893
-bpy.context.object.data.sky.backscattered_light = 0.0
-bpy.context.object.data.sky.sun_intensity = 4.0
-bpy.context.object.data.sky.atmosphere_inscattering = 1.0
-bpy.context.object.data.sky.atmosphere_extinction = 1.0
+bpy.context.lamp.sky.atmosphere_turbidity = 4.0
+bpy.context.lamp.sky.sky_blend_type = 'ADD'
+bpy.context.lamp.sky.sky_blend = 1.0
+bpy.context.lamp.sky.horizon_brightness = 10.0
+bpy.context.lamp.sky.spread = 1.49011614159e-09
+bpy.context.lamp.sky.sky_color_space = 'SMPTE'
+bpy.context.lamp.sky.sky_exposure = 1.0
+bpy.context.lamp.sky.sun_brightness = 1.00000011921
+bpy.context.lamp.sky.sun_size = 1.00000166893
+bpy.context.lamp.sky.backscattered_light = 0.0
+bpy.context.lamp.sky.sun_intensity = 4.0
+bpy.context.lamp.sky.atmosphere_inscattering = 1.0
+bpy.context.lamp.sky.atmosphere_extinction = 1.0
diff --git a/release/scripts/presets/sunsky/desert.py b/release/scripts/presets/sunsky/desert.py
index f68ea23845b..8dd587a6eaf 100644
--- a/release/scripts/presets/sunsky/desert.py
+++ b/release/scripts/presets/sunsky/desert.py
@@ -1,14 +1,14 @@
import bpy
-bpy.context.object.data.sky.atmosphere_turbidity = 6.0
-bpy.context.object.data.sky.sky_blend_type = 'ADD'
-bpy.context.object.data.sky.sky_blend = 1.0
-bpy.context.object.data.sky.horizon_brightness = 4.99999761581
-bpy.context.object.data.sky.spread = 1.49011614159e-09
-bpy.context.object.data.sky.sky_color_space = 'SMPTE'
-bpy.context.object.data.sky.sky_exposure = 1.0
-bpy.context.object.data.sky.sun_brightness = 1.00000011921
-bpy.context.object.data.sky.sun_size = 4.0
-bpy.context.object.data.sky.backscattered_light = 1.0
-bpy.context.object.data.sky.sun_intensity = 1.0
-bpy.context.object.data.sky.atmosphere_inscattering = 1.0
-bpy.context.object.data.sky.atmosphere_extinction = 1.0
+bpy.context.lamp.sky.atmosphere_turbidity = 6.0
+bpy.context.lamp.sky.sky_blend_type = 'ADD'
+bpy.context.lamp.sky.sky_blend = 1.0
+bpy.context.lamp.sky.horizon_brightness = 4.99999761581
+bpy.context.lamp.sky.spread = 1.49011614159e-09
+bpy.context.lamp.sky.sky_color_space = 'SMPTE'
+bpy.context.lamp.sky.sky_exposure = 1.0
+bpy.context.lamp.sky.sun_brightness = 1.00000011921
+bpy.context.lamp.sky.sun_size = 4.0
+bpy.context.lamp.sky.backscattered_light = 1.0
+bpy.context.lamp.sky.sun_intensity = 1.0
+bpy.context.lamp.sky.atmosphere_inscattering = 1.0
+bpy.context.lamp.sky.atmosphere_extinction = 1.0
diff --git a/release/scripts/presets/sunsky/mountain.py b/release/scripts/presets/sunsky/mountain.py
index 9b81ffd4399..f0540af8100 100644
--- a/release/scripts/presets/sunsky/mountain.py
+++ b/release/scripts/presets/sunsky/mountain.py
@@ -1,14 +1,14 @@
import bpy
-bpy.context.object.data.sky.atmosphere_turbidity = 2.00000023842
-bpy.context.object.data.sky.sky_blend_type = 'ADD'
-bpy.context.object.data.sky.sky_blend = 1.0
-bpy.context.object.data.sky.horizon_brightness = 0.100000016391
-bpy.context.object.data.sky.spread = 1.0
-bpy.context.object.data.sky.sky_color_space = 'SMPTE'
-bpy.context.object.data.sky.sky_exposure = 1.0
-bpy.context.object.data.sky.sun_brightness = 1.99999988079
-bpy.context.object.data.sky.sun_size = 4.0
-bpy.context.object.data.sky.backscattered_light = -1.0
-bpy.context.object.data.sky.sun_intensity = 10.0
-bpy.context.object.data.sky.atmosphere_inscattering = 1.0
-bpy.context.object.data.sky.atmosphere_extinction = 1.0
+bpy.context.lamp.sky.atmosphere_turbidity = 2.00000023842
+bpy.context.lamp.sky.sky_blend_type = 'ADD'
+bpy.context.lamp.sky.sky_blend = 1.0
+bpy.context.lamp.sky.horizon_brightness = 0.100000016391
+bpy.context.lamp.sky.spread = 1.0
+bpy.context.lamp.sky.sky_color_space = 'SMPTE'
+bpy.context.lamp.sky.sky_exposure = 1.0
+bpy.context.lamp.sky.sun_brightness = 1.99999988079
+bpy.context.lamp.sky.sun_size = 4.0
+bpy.context.lamp.sky.backscattered_light = -1.0
+bpy.context.lamp.sky.sun_intensity = 10.0
+bpy.context.lamp.sky.atmosphere_inscattering = 1.0
+bpy.context.lamp.sky.atmosphere_extinction = 1.0
diff --git a/release/scripts/presets/tracking_camera/Blackmagic_Pocket_Cinema_Camera.py b/release/scripts/presets/tracking_camera/Blackmagic_Pocket_Cinema_Camera.py
new file mode 100644
index 00000000000..a9c81f47c21
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Blackmagic_Pocket_Cinema_Camera.py
@@ -0,0 +1,9 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 12.48
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Blackmagic_Production_Camera_4K.py b/release/scripts/presets/tracking_camera/Blackmagic_Production_Camera_4K.py
new file mode 100644
index 00000000000..d644d2a26c9
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Blackmagic_Production_Camera_4K.py
@@ -0,0 +1,9 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 21.12
+camera.units = 'MILLIMETERS'
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 29b75e64fca..c1f75c74bb4 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -249,9 +249,9 @@ class SubdivisionSet(Operator):
if mod.type == 'MULTIRES':
if not relative:
if level > mod.total_levels:
- sub = level - mod.total_levels
- for i in range (0, sub):
- bpy.ops.object.multires_subdivide(modifier="Multires")
+ sub = level - mod.total_levels
+ for i in range (0, sub):
+ bpy.ops.object.multires_subdivide(modifier="Multires")
if obj.mode == 'SCULPT':
if mod.sculpt_levels != level:
@@ -775,22 +775,15 @@ class DupliOffsetFromCursor(Operator):
bl_label = "Set Offset From Cursor"
bl_options = {'REGISTER', 'UNDO'}
- group = IntProperty(
- name="Group",
- description="Group index to set offset for",
- default=0,
- )
-
@classmethod
def poll(cls, context):
return (context.active_object is not None)
def execute(self, context):
scene = context.scene
- ob = context.active_object
- group = self.group
+ group = context.group
- ob.users_group[group].dupli_offset = scene.cursor_location
+ group.dupli_offset = scene.cursor_location
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 556d34bb0ac..32688299b76 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -289,6 +289,10 @@ def obj_bb_minmax(obj, min_co, max_co):
max_co[0] = max(bb_vec[0], max_co[0])
max_co[1] = max(bb_vec[1], max_co[1])
max_co[2] = max(bb_vec[2], max_co[2])
+
+
+def grid_location(x, y):
+ return (x * 200, y * 150)
class QuickSmoke(Operator):
@@ -298,10 +302,11 @@ class QuickSmoke(Operator):
style = EnumProperty(
name="Smoke Style",
- items=(('STREAM', "Stream", ""),
+ items=(('SMOKE', "Smoke", ""),
('FIRE', "Fire", ""),
+ ('BOTH', "Smoke + Fire", ""),
),
- default='STREAM',
+ default='SMOKE',
)
show_flows = BoolProperty(
@@ -327,8 +332,8 @@ class QuickSmoke(Operator):
bpy.ops.object.modifier_add(fake_context, type='SMOKE')
obj.modifiers[-1].smoke_type = 'FLOW'
- if self.style == 'FIRE':
- obj.modifiers[-1].flow_settings.smoke_flow_type = 'FIRE'
+ # set type
+ obj.modifiers[-1].flow_settings.smoke_flow_type = self.style
if not self.show_flows:
obj.draw_type = 'WIRE'
@@ -348,57 +353,177 @@ class QuickSmoke(Operator):
# setup smoke domain
bpy.ops.object.modifier_add(type='SMOKE')
obj.modifiers[-1].smoke_type = 'DOMAIN'
- if self.style == 'FIRE':
+ if self.style == 'FIRE' or self.style == 'BOTH':
obj.modifiers[-1].domain_settings.use_high_resolution = True
- # create a volume material with a voxel data texture for the domain
- bpy.ops.object.material_slot_add()
+ # Setup material
+
+ # Cycles
+ if context.scene.render.use_shading_nodes:
+ bpy.ops.object.material_slot_add()
+
+ mat = bpy.data.materials.new("Smoke Domain Material")
+ obj.material_slots[0].material = mat
+
+ # Make sure we use nodes
+ mat.use_nodes = True
+
+ # Set node variables and clear the default nodes
+ tree = mat.node_tree
+ nodes = tree.nodes
+ links = tree.links
+
+ nodes.clear()
+
+ # Create shader nodes
+
+ # Material output
+ node_out = nodes.new(type='ShaderNodeOutputMaterial')
+ node_out.location = grid_location(6, 1)
+
+ # Add shader 1
+ node_add_shader_1 = nodes.new(type='ShaderNodeAddShader')
+ node_add_shader_1.location = grid_location(5, 1)
+ links.new(node_add_shader_1.outputs["Shader"],
+ node_out.inputs["Volume"])
+
+ # Smoke
+
+ # Add shader 2
+ node_add_shader_2 = nodes.new(type='ShaderNodeAddShader')
+ node_add_shader_2.location = grid_location(4, 2)
+ links.new(node_add_shader_2.outputs["Shader"],
+ node_add_shader_1.inputs[0])
+
+ # Volume scatter
+ node_scatter = nodes.new(type='ShaderNodeVolumeScatter')
+ node_scatter.location = grid_location(3, 3)
+ links.new(node_scatter.outputs["Volume"],
+ node_add_shader_2.inputs[0])
+
+ # Volume absorption
+ node_absorption = nodes.new(type='ShaderNodeVolumeAbsorption')
+ node_absorption.location = grid_location(3, 2)
+ links.new(node_absorption.outputs["Volume"],
+ node_add_shader_2.inputs[1])
+
+ # Density Multiplier
+ node_densmult = nodes.new(type='ShaderNodeMath')
+ node_densmult.location = grid_location(2, 2)
+ node_densmult.operation = 'MULTIPLY'
+ node_densmult.inputs[1].default_value = 5.0
+ links.new(node_densmult.outputs["Value"],
+ node_scatter.inputs["Density"])
+ links.new(node_densmult.outputs["Value"],
+ node_absorption.inputs["Density"])
+
+ # Attribute "density"
+ node_attrib_density = nodes.new(type='ShaderNodeAttribute')
+ node_attrib_density.attribute_name = "density"
+ node_attrib_density.location = grid_location(1, 2)
+ links.new(node_attrib_density.outputs["Fac"],
+ node_densmult.inputs[0])
+
+ # Attribute "color"
+ node_attrib_color = nodes.new(type='ShaderNodeAttribute')
+ node_attrib_color.attribute_name = "color"
+ node_attrib_color.location = grid_location(2, 3)
+ links.new(node_attrib_color.outputs["Color"],
+ node_scatter.inputs["Color"])
+ links.new(node_attrib_color.outputs["Color"],
+ node_absorption.inputs["Color"])
+
+ # Fire
+
+ # Emission
+ node_emission = nodes.new(type='ShaderNodeEmission')
+ node_emission.inputs["Color"].default_value = (0.8, 0.1, 0.01, 1.0)
+ node_emission.location = grid_location(4, 1)
+ links.new(node_emission.outputs["Emission"],
+ node_add_shader_1.inputs[1])
+
+ # Flame strength multiplier
+ node_flame_strength_mult = nodes.new(type='ShaderNodeMath')
+ node_flame_strength_mult.location = grid_location(3, 1)
+ node_flame_strength_mult.operation = 'MULTIPLY'
+ node_flame_strength_mult.inputs[1].default_value = 2.5
+ links.new(node_flame_strength_mult.outputs["Value"],
+ node_emission.inputs["Strength"])
+
+ # Color ramp Flame
+ node_flame_ramp = nodes.new(type='ShaderNodeValToRGB')
+ node_flame_ramp.location = grid_location(1, 1)
+ ramp = node_flame_ramp.color_ramp
+ ramp.interpolation = 'EASE'
+
+ # orange
+ elem = ramp.elements.new(0.5)
+ elem.color = (1.0, 0.128, 0.0, 1.0)
+
+ # yellow
+ elem = ramp.elements.new(0.9)
+ elem.color = (0.9, 0.6, 0.1, 1.0)
+
+ links.new(node_flame_ramp.outputs["Color"],
+ node_emission.inputs["Color"])
+
+ # Attribute "flame"
+ node_attrib_flame = nodes.new(type='ShaderNodeAttribute')
+ node_attrib_flame.attribute_name = "flame"
+ node_attrib_flame.location = grid_location(0, 1)
+ links.new(node_attrib_flame.outputs["Fac"],
+ node_flame_ramp.inputs["Fac"])
+ links.new(node_attrib_flame.outputs["Fac"],
+ node_flame_strength_mult.inputs[0])
+
+ # Blender Internal
+ else:
+ # create a volume material with a voxel data texture for the domain
+ bpy.ops.object.material_slot_add()
+
+ mat = bpy.data.materials.new("Smoke Domain Material")
+ obj.material_slots[0].material = mat
+ mat.type = 'VOLUME'
+ mat.volume.density = 0
+ mat.volume.density_scale = 5
+ mat.volume.step_size = 0.1
+
+ tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA')
+ tex.voxel_data.domain_object = obj
+ tex.voxel_data.interpolation = 'TRICUBIC_BSPLINE'
+
+ tex_slot = mat.texture_slots.add()
+ tex_slot.texture = tex
+ tex_slot.texture_coords = 'ORCO'
+ tex_slot.use_map_color_emission = False
+ tex_slot.use_map_density = True
+ tex_slot.use_map_color_reflection = True
+
+ # for fire add a second texture for flame emission
+ mat.volume.emission_color = Vector((0.0, 0.0, 0.0))
+ tex = bpy.data.textures.new("Flame", 'VOXEL_DATA')
+ tex.voxel_data.domain_object = obj
+ tex.voxel_data.smoke_data_type = 'SMOKEFLAME'
+ tex.voxel_data.interpolation = 'TRICUBIC_BSPLINE'
+ tex.use_color_ramp = True
- mat = bpy.data.materials.new("Smoke Domain Material")
- obj.material_slots[0].material = mat
- mat.type = 'VOLUME'
- mat.volume.density = 0
- mat.volume.density_scale = 5
- mat.volume.step_size = 0.1
-
- tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA')
- tex.voxel_data.domain_object = obj
- tex.voxel_data.interpolation = 'TRICUBIC_BSPLINE'
-
- tex_slot = mat.texture_slots.add()
- tex_slot.texture = tex
- tex_slot.use_map_color_emission = False
- tex_slot.use_map_density = True
- tex_slot.use_map_color_reflection = True
-
- # for fire add a second texture for flame emission
- mat.volume.emission_color = Vector((0.0, 0.0, 0.0))
- tex = bpy.data.textures.new("Flame", 'VOXEL_DATA')
- tex.voxel_data.domain_object = obj
- tex.voxel_data.smoke_data_type = 'SMOKEFLAME'
- tex.voxel_data.interpolation = 'TRICUBIC_BSPLINE'
- tex.use_color_ramp = True
-
- tex_slot = mat.texture_slots.add()
- tex_slot.texture = tex
-
- # add color ramp for flame color
- ramp = tex.color_ramp
- # dark orange
- elem = ramp.elements.new(0.333)
- elem.color[0] = 0.2
- elem.color[1] = 0.03
- elem.color[2] = 0
- elem.color[3] = 1
- # yellow glow
- elem = ramp.elements.new(0.666)
- elem.color[0] = elem.color[3] = 1
- elem.color[1] = 0.65
- elem.color[2] = 0.25
-
- mat.texture_slots[1].use_map_density = True
- mat.texture_slots[1].use_map_emission = True
- mat.texture_slots[1].emission_factor = 5
+ tex_slot = mat.texture_slots.add()
+ tex_slot.texture = tex
+ tex_slot.texture_coords = 'ORCO'
+
+ # add color ramp for flame color
+ ramp = tex.color_ramp
+ # dark orange
+ elem = ramp.elements.new(0.333)
+ elem.color = (0.2, 0.03, 0.0, 1.0)
+
+ # yellow glow
+ elem = ramp.elements.new(0.666)
+ elem.color = (1, 0.65, 0.25, 1.0)
+
+ mat.texture_slots[1].use_map_density = True
+ mat.texture_slots[1].use_map_emission = True
+ mat.texture_slots[1].emission_factor = 5
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index 8b0ed7d9942..f89792bea6e 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -253,7 +253,7 @@ class AddPresetCamera(AddPresetBase, Operator):
preset_menu = "CAMERA_MT_presets"
preset_defines = [
- "cam = bpy.context.object.data"
+ "cam = bpy.context.camera"
]
preset_subdir = "camera"
@@ -352,7 +352,7 @@ class AddPresetSunSky(AddPresetBase, Operator):
preset_menu = "LAMP_MT_sunsky_presets"
preset_defines = [
- "sky = bpy.context.object.data.sky"
+ "sky = bpy.context.lamp.sky"
]
preset_values = [
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 6f54c051c0b..8f618e0632e 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -470,9 +470,7 @@ def lightmap_uvpack(meshes,
pretty_faces.append(pf_parent)
w, h = pf_parent.width, pf_parent.height
-
- if w > h:
- raise "error"
+ assert(w <= h)
if w == h:
even_dict.setdefault(w, []).append(pf_parent)
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index bf8b10ac4af..aa8a1742c1e 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -634,7 +634,7 @@ def packIslands(islandList):
# print 'Box Packing Time:', time.time() - time1
#if len(pa ckedLs) != len(islandList):
- # raise "Error packed boxes differs from original length"
+ # raise ValueError("Packed boxes differs from original length")
#print '\tWriting Packed Data to faces'
#XXX Window.DrawProgressBar(0.8, "Writing Packed Data to faces")
diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
index 68c9bc143be..ecb1ecf7f47 100644
--- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py
+++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
@@ -109,7 +109,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
active_col_layer = me.vertex_colors[0].data
if not active_col_layer:
- return
+ return {'CANCELLED'}
use_paint_mask = me.use_paint_mask
diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py
index 85cc9210c2d..df4a93bb87f 100644
--- a/release/scripts/startup/bl_operators/view3d.py
+++ b/release/scripts/startup/bl_operators/view3d.py
@@ -169,6 +169,13 @@ class VIEW3D_OT_select_or_deselect_all(Operator):
default=False,
)
+ @classmethod
+ def poll(cls, context):
+ active_object = context.active_object
+ if active_object:
+ return active_object.mode in {'EDIT', 'OBJECT', 'POSE'}
+ return True
+
def invoke(self, context, event):
x = event.mouse_region_x
y = event.mouse_region_y
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 4281c908afd..5c3f94a8739 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -527,7 +527,76 @@ class WM_OT_context_menu_enum(Operator):
context.window_manager.popup_menu(draw_func=draw_cb, title=prop.name, icon=prop.icon)
- return {'PASS_THROUGH'}
+ return {'FINISHED'}
+
+
+class WM_OT_context_pie_enum(Operator):
+ bl_idname = "wm.context_pie_enum"
+ bl_label = "Context Enum Pie"
+ bl_options = {'UNDO', 'INTERNAL'}
+ data_path = rna_path_prop
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ data_path = self.data_path
+ value = context_path_validate(context, data_path)
+
+ if value is Ellipsis:
+ return {'PASS_THROUGH'}
+
+ base_path, prop_string = data_path.rsplit(".", 1)
+ value_base = context_path_validate(context, base_path)
+ prop = value_base.bl_rna.properties[prop_string]
+
+ def draw_cb(self, context):
+ layout = self.layout
+ layout.prop(value_base, prop_string, expand=True)
+
+ wm.popup_menu_pie(draw_func=draw_cb, title=prop.name, icon=prop.icon, event=event)
+
+ return {'FINISHED'}
+
+
+class WM_OT_operator_pie_enum(Operator):
+ bl_idname = "wm.operator_pie_enum"
+ bl_label = "Operator Enum Pie"
+ bl_options = {'UNDO', 'INTERNAL'}
+ data_path = StringProperty(
+ name="Operator",
+ description="Operator name (in python as string)",
+ maxlen=1024,
+ )
+ prop_string = StringProperty(
+ name="Property",
+ description="Property name (as a string)",
+ maxlen=1024,
+ )
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+
+ data_path = self.data_path
+ prop_string = self.prop_string
+
+ # same as eval("bpy.ops." + data_path)
+ op_mod_str, ob_id_str = data_path.split(".", 1)
+ op = getattr(getattr(bpy.ops, op_mod_str), ob_id_str)
+ del op_mod_str, ob_id_str
+
+ try:
+ op_rna = op.get_rna()
+ except KeyError:
+ self.report({'ERROR'}, "Operator not found: bpy.ops.%s" % data_path)
+ return {'CANCELLED'}
+
+ def draw_cb(self, context):
+ layout = self.layout
+ pie = layout.menu_pie()
+ pie.operator_enum(data_path, prop_string)
+
+ wm.popup_menu_pie(draw_func=draw_cb, title=op_rna.bl_rna.name, event=event)
+
+ return {'FINISHED'}
class WM_OT_context_set_id(Operator):
@@ -1033,13 +1102,13 @@ rna_property = StringProperty(
rna_min = FloatProperty(
name="Min",
- default=0.0,
+ default=-10000.0,
precision=3,
)
rna_max = FloatProperty(
name="Max",
- default=1.0,
+ default=10000.0,
precision=3,
)
@@ -1883,7 +1952,7 @@ class WM_OT_addon_install(Operator):
addons_old = {mod.__name__ for mod in addon_utils.modules()}
- #check to see if the file is in compressed format (.zip)
+ # check to see if the file is in compressed format (.zip)
if zipfile.is_zipfile(pyfile):
try:
file_to_extract = zipfile.ZipFile(pyfile, 'r')
@@ -1916,7 +1985,7 @@ class WM_OT_addon_install(Operator):
self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
return {'CANCELLED'}
- #if not compressed file just copy into the addon path
+ # if not compressed file just copy into the addon path
try:
shutil.copyfile(pyfile, path_dest)
diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index 50107604b3b..4baf31a591b 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -788,6 +788,10 @@ class ConstraintButtonsPanel():
row.prop(con, "use_active_clip")
row.prop(con, "use_3d_position")
+ sub = row.column()
+ sub.active = not con.use_3d_position
+ sub.prop(con, "use_undistorted_position")
+
col = layout.column()
if not con.use_active_clip:
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index 0f5039a40ea..c07e9d677e7 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -253,7 +253,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel):
active = pchan.is_in_ik_chain
split = layout.split(percentage=0.25)
- split.prop(pchan, "lock_ik_x", text="X", icon_only=True)
+ split.prop(pchan, "lock_ik_x", text="X")
split.active = active
row = split.row()
row.prop(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
@@ -270,7 +270,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel):
sub.active = pchan.lock_ik_x is False and pchan.use_ik_limit_x and active
split = layout.split(percentage=0.25)
- split.prop(pchan, "lock_ik_y", text="Y", icon_only=True)
+ split.prop(pchan, "lock_ik_y", text="Y")
split.active = active
row = split.row()
row.prop(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
@@ -288,7 +288,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel):
sub.active = pchan.lock_ik_y is False and pchan.use_ik_limit_y and active
split = layout.split(percentage=0.25)
- split.prop(pchan, "lock_ik_z", text="Z", icon_only=True)
+ split.prop(pchan, "lock_ik_z", text="Z")
split.active = active
sub = split.row()
sub.prop(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py
index b19fce1c7d0..c93bebf2673 100644
--- a/release/scripts/startup/bl_ui/properties_data_empty.py
+++ b/release/scripts/startup/bl_ui/properties_data_empty.py
@@ -42,7 +42,7 @@ class DATA_PT_empty(DataButtonsPanel, Panel):
layout.prop(ob, "empty_draw_type", text="Display")
if ob.empty_draw_type == 'IMAGE':
- layout.template_ID(ob, "data", open="image.open")
+ layout.template_ID(ob, "data", open="image.open", unlink="object.unlink_data")
layout.template_image(ob, "data", ob.image_user, compact=True)
row = layout.row(align=True)
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 41cf93f71ad..909c6ab0b56 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -29,7 +29,8 @@ class MESH_MT_vertex_group_specials(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("object.vertex_group_sort", icon='SORTALPHA')
+ layout.operator("object.vertex_group_sort", icon='SORTALPHA').sort_type = "NAME"
+ layout.operator("object.vertex_group_sort", icon='ARMATURE_DATA', text="Sort by Bone Hierarchy").sort_type = "BONE_HIERARCHY"
layout.operator("object.vertex_group_copy", icon='COPY_ID')
layout.operator("object.vertex_group_copy_to_linked", icon='LINK_AREA')
layout.operator("object.vertex_group_copy_to_selected", icon='LINK_AREA')
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 60187ff1cd5..efc430db50f 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -127,6 +127,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "width")
col.prop(md, "segments")
col.prop(md, "profile")
+ col.prop(md, "material")
col = split.column()
col.prop(md, "use_only_vertices")
@@ -817,6 +818,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "use_even_offset")
col.prop(md, "use_quality_normals")
col.prop(md, "use_rim")
+ col_rim = col.column()
+ col_rim.active = md.use_rim
+ col_rim.prop(md, "use_rim_only")
col.separator()
diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py
index c5716dff86d..58818e90440 100644
--- a/release/scripts/startup/bl_ui/properties_freestyle.py
+++ b/release/scripts/startup/bl_ui/properties_freestyle.py
@@ -39,7 +39,7 @@ class RenderFreestyleButtonsPanel():
class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel):
bl_label = "Freestyle"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'CYCLES'}
def draw_header(self, context):
rd = context.scene.render
@@ -59,10 +59,6 @@ class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel):
if (rd.line_thickness_mode == 'ABSOLUTE'):
layout.prop(rd, "line_thickness")
- row = layout.row()
- row.label(text="Line style settings are in the Render Layers tab")
- row.operator("wm.properties_context_change", text="", icon='RENDERLAYERS').context = 'RENDER_LAYER'
-
# Render layer properties
@@ -115,7 +111,7 @@ class RENDER_MT_lineset_specials(Menu):
class RENDERLAYER_PT_freestyle(RenderLayerFreestyleButtonsPanel, Panel):
bl_label = "Freestyle"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'CYCLES'}
def draw(self, context):
layout = self.layout
@@ -169,7 +165,7 @@ class RENDERLAYER_PT_freestyle(RenderLayerFreestyleButtonsPanel, Panel):
class RENDERLAYER_PT_freestyle_lineset(RenderLayerFreestyleEditorButtonsPanel, Panel):
bl_label = "Freestyle Line Set"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'CYCLES'}
def draw_edge_type_buttons(self, box, lineset, edge_type):
# property names
@@ -261,7 +257,7 @@ class RENDERLAYER_PT_freestyle_lineset(RenderLayerFreestyleEditorButtonsPanel, P
class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel, Panel):
bl_label = "Freestyle Line Style"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'CYCLES'}
def draw_modifier_box_header(self, box, modifier):
row = box.row()
@@ -678,7 +674,10 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
layout.separator()
row = layout.row()
- row.prop(linestyle, "use_texture")
+ if rd.use_shading_nodes:
+ row.prop(linestyle, "use_nodes")
+ else:
+ row.prop(linestyle, "use_texture")
row.prop(linestyle, "texture_spacing", text="Spacing Along Stroke")
row = layout.row()
@@ -711,7 +710,7 @@ class MaterialFreestyleButtonsPanel():
class MATERIAL_PT_freestyle_line(MaterialFreestyleButtonsPanel, Panel):
bl_label = "Freestyle Line"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'} # TODO: 'CYCLES'
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'CYCLES'}
def draw(self, context):
layout = self.layout
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 6b7e7b47281..e6d6a3952ea 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Panel
+from bpy.types import Panel, Menu
from rna_prop_ui import PropertyPanel
@@ -151,6 +151,16 @@ class OBJECT_PT_relations(ObjectButtonsPanel, Panel):
sub.prop_search(ob, "parent_bone", parent.data, "bones", text="")
sub.active = (parent is not None)
+class GROUP_MT_specials(Menu):
+ bl_label = "Group Specials"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("object.group_unlink", icon='X')
+ layout.operator("object.grouped_select")
+ layout.operator("object.dupli_offset_from_cursor")
+
class OBJECT_PT_groups(ObjectButtonsPanel, Panel):
bl_label = "Groups"
@@ -167,8 +177,6 @@ class OBJECT_PT_groups(ObjectButtonsPanel, Panel):
row.operator("object.group_add", text="Add to Group")
row.operator("object.group_add", text="", icon='ZOOMIN')
- # XXX, this is bad practice, yes, I wrote it :( - campbell
- index = 0
obj_name = obj.name
for group in bpy.data.groups:
# XXX this is slow and stupid!, we need 2 checks, one thats fast
@@ -183,6 +191,7 @@ class OBJECT_PT_groups(ObjectButtonsPanel, Panel):
row = col.box().row()
row.prop(group, "name", text="")
row.operator("object.group_remove", text="", icon='X', emboss=False)
+ row.menu("GROUP_MT_specials", icon='DOWNARROW_HLT', text="")
split = col.box().split()
@@ -192,10 +201,6 @@ class OBJECT_PT_groups(ObjectButtonsPanel, Panel):
col = split.column()
col.prop(group, "dupli_offset", text="")
- props = col.operator("object.dupli_offset_from_cursor", text="From Cursor")
- props.group = index
- index += 1
-
class OBJECT_PT_display(ObjectButtonsPanel, Panel):
bl_label = "Display"
@@ -301,10 +306,11 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
split = layout.split()
- col = split.column()
- col.label(text="Tracking Axes:")
- col.prop(ob, "track_axis", text="Axis")
- col.prop(ob, "up_axis", text="Up Axis")
+ if context.scene.render.engine != 'BLENDER_GAME':
+ col = split.column()
+ col.label(text="Tracking Axes:")
+ col.prop(ob, "track_axis", text="Axis")
+ col.prop(ob, "up_axis", text="Up Axis")
col = split.column()
col.prop(ob, "use_slow_parent")
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 462ca2e85ca..5c758b6568b 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -17,6 +17,7 @@
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
+from bpy.types import Menu
class UnifiedPaintPanel():
@@ -50,6 +51,10 @@ class UnifiedPaintPanel():
row.prop(ups, "use_unified_strength", text="Strength")
if context.weight_paint_object:
parent.prop(ups, "use_unified_weight", text="Weight")
+ elif context.vertex_paint_object or context.image_paint_object:
+ parent.prop(ups, "use_unified_color", text="Color")
+ else:
+ parent.prop(ups, "use_unified_color", text="Color")
@staticmethod
def prop_unified_size(parent, context, brush, prop_name, icon='NONE', text="", slider=False):
@@ -69,6 +74,155 @@ class UnifiedPaintPanel():
ptr = ups if ups.use_unified_weight else brush
parent.prop(ptr, prop_name, icon=icon, text=text, slider=slider)
+ @staticmethod
+ def prop_unified_color(parent, context, brush, prop_name, text=""):
+ ups = context.tool_settings.unified_paint_settings
+ ptr = ups if ups.use_unified_color else brush
+ parent.prop(ptr, prop_name, text=text)
+
+ @staticmethod
+ def prop_unified_color_picker(parent, context, brush, prop_name, value_slider=True):
+ ups = context.tool_settings.unified_paint_settings
+ ptr = ups if ups.use_unified_color else brush
+ parent.template_color_picker(ptr, prop_name, value_slider=value_slider)
+
+
+class VIEW3D_MT_tools_projectpaint_clone(Menu):
+ bl_label = "Clone Layer"
+
+ def draw(self, context):
+ layout = self.layout
+
+ for i, tex in enumerate(context.active_object.data.uv_textures):
+ props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
+ props.data_path = "active_object.data.uv_texture_clone_index"
+ props.value = i
+
+
+def brush_texpaint_common(panel, context, layout, brush, settings, projpaint=False):
+ capabilities = brush.image_paint_capabilities
+
+ col = layout.column()
+
+ if brush.image_tool in {'DRAW', 'FILL'}:
+ if brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'}:
+ if not brush.use_gradient:
+ panel.prop_unified_color_picker(col, context, brush, "color", value_slider=True)
+
+ if settings.palette:
+ col.template_palette(settings, "palette", color=True)
+
+ if brush.use_gradient:
+ col.label("Gradient Colors")
+ col.template_color_ramp(brush, "gradient", expand=True)
+
+ if brush.image_tool != 'FILL':
+ col.label("Background Color")
+ row = col.row(align=True)
+ panel.prop_unified_color(row, context, brush, "secondary_color", text="")
+
+ if brush.image_tool == 'DRAW':
+ col.prop(brush, "gradient_stroke_mode", text="Mode")
+ if brush.gradient_stroke_mode in {'SPACING_REPEAT', 'SPACING_CLAMP'}:
+ col.prop(brush, "grad_spacing")
+ elif brush.image_tool == 'FILL':
+ col.prop(brush, "gradient_fill_mode")
+ else:
+ row = col.row(align=True)
+ panel.prop_unified_color(row, context, brush, "color", text="")
+ if brush.image_tool == 'FILL':
+ col.prop(brush, "fill_threshold")
+ else:
+ panel.prop_unified_color(row, context, brush, "secondary_color", text="")
+ row.separator()
+ row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="")
+
+ elif brush.image_tool == 'SOFTEN':
+ col = layout.column(align=True)
+ col.row().prop(brush, "direction", expand=True)
+ col.separator()
+ col.prop(brush, "sharp_threshold")
+ if not projpaint:
+ col.prop(brush, "blur_kernel_radius")
+ col.separator()
+ col.prop(brush, "blur_mode")
+ elif brush.image_tool == 'MASK':
+ col.prop(brush, "weight", text="Mask Value", slider=True)
+
+ elif brush.image_tool == 'CLONE':
+ col.separator()
+ if projpaint:
+ if settings.mode == 'MATERIAL':
+ col.prop(settings, "use_clone_layer", text="Clone from paint slot")
+ elif settings.mode == 'IMAGE':
+ col.prop(settings, "use_clone_layer", text="Clone from image/UV map")
+
+ if settings.use_clone_layer:
+ ob = context.active_object
+ col = layout.column()
+
+ if settings.mode == 'MATERIAL':
+ if len(ob.material_slots) > 1:
+ col.label("Materials")
+ col.template_list("MATERIAL_UL_matslots", "",
+ ob, "material_slots",
+ ob, "active_material_index", rows=2)
+
+ mat = ob.active_material
+ if mat:
+ col.label("Clone Slot")
+ col.template_list("TEXTURE_UL_texpaintslots", "",
+ mat, "texture_paint_images",
+ mat, "paint_clone_slot", rows=2)
+
+ elif settings.mode == 'IMAGE':
+ mesh = ob.data
+
+ clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else ""
+ col.label("Image")
+ col.template_ID(settings, "clone_image")
+ col.label("UV Map")
+ col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text, translate=False)
+
+
+ else:
+ col.prop(brush, "clone_image", text="Image")
+ col.prop(brush, "clone_alpha", text="Alpha")
+
+
+
+ col.separator()
+
+ if capabilities.has_radius:
+ row = col.row(align=True)
+ panel.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
+ panel.prop_unified_size(row, context, brush, "use_pressure_size")
+
+ row = col.row(align=True)
+
+ if capabilities.has_space_attenuation:
+ row.prop(brush, "use_space_attenuation", toggle=True, icon_only=True)
+
+ panel.prop_unified_strength(row, context, brush, "strength", text="Strength")
+ panel.prop_unified_strength(row, context, brush, "use_pressure_strength")
+
+ if brush.image_tool in {'DRAW', 'FILL'}:
+ col.separator()
+ col.prop(brush, "blend", text="Blend")
+
+ col = layout.column()
+
+ # use_accumulate
+ if capabilities.has_accumulate:
+ col = layout.column(align=True)
+ col.prop(brush, "use_accumulate")
+
+ col.prop(brush, "use_alpha")
+ col.prop(brush, "use_gradient")
+
+ col.separator()
+ col.template_ID(settings, "palette", new="palette.new")
+
# Used in both the View3D toolbar and texture properties
def brush_texture_settings(layout, brush, sculpt):
@@ -136,6 +290,7 @@ def brush_mask_texture_settings(layout, brush):
layout.operator("brush.stencil_reset_transform").mask = True
col = layout.column()
+ col.prop(brush, "use_pressure_masking", text="")
col.label(text="Angle:")
col.active = brush.brush_capabilities.has_texture_angle
col.prop(mask_tex_slot, "angle", text="")
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index 626cdaa8b1b..faf0d4cb0e8 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -1172,7 +1172,6 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
col = split.column()
factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
-
layout.separator()
if not isinstance(idblock, ParticleSettings):
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 96ad70e0015..13aad4c3888 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -261,7 +261,7 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
layout = self.layout
sc = context.space_data
- clip = sc.clip
+ # clip = sc.clip
col = layout.column(align=True)
row = col.row(align=True)
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 97c89df0693..8fd0ded17f7 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -22,6 +22,7 @@ from bpy.types import Header, Menu, Panel
from bl_ui.properties_paint_common import (
UnifiedPaintPanel,
brush_texture_settings,
+ brush_texpaint_common,
brush_mask_texture_settings,
)
from bl_ui.properties_grease_pencil_common import GreasePencilPanel
@@ -31,13 +32,11 @@ from bpy.app.translations import pgettext_iface as iface_
class ImagePaintPanel(UnifiedPaintPanel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
- bl_category = "Tools"
-class BrushButtonsPanel:
+class BrushButtonsPanel(UnifiedPaintPanel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
- bl_category = "Tools"
@classmethod
def poll(cls, context):
@@ -66,6 +65,7 @@ class IMAGE_MT_view(Menu):
sima = context.space_data
uv = sima.uv_editor
toolsettings = context.tool_settings
+ paint = toolsettings.image_paint
show_uvedit = sima.show_uvedit
show_render = sima.show_render
@@ -80,6 +80,8 @@ class IMAGE_MT_view(Menu):
layout.prop(toolsettings, "show_uv_local_view")
layout.prop(uv, "show_other_objects")
+ if paint.brush and (context.image_paint_object or sima.mode == 'PAINT'):
+ layout.prop(uv, "show_texpaint")
layout.separator()
@@ -140,6 +142,24 @@ class IMAGE_MT_select(Menu):
layout.operator("uv.select_split")
+class IMAGE_MT_brush(Menu):
+ bl_label = "Brush"
+
+ def draw(self, context):
+ layout = self.layout
+ toolsettings = context.tool_settings
+ settings = toolsettings.image_paint
+ brush = settings.brush
+
+ ups = context.tool_settings.unified_paint_settings
+ layout.prop(ups, "use_unified_size", text="Unified Size")
+ layout.prop(ups, "use_unified_strength", text="Unified Strength")
+ layout.separator()
+
+ # brush tool
+ layout.prop_menu_enum(brush, "image_tool")
+
+
class IMAGE_MT_image(Menu):
bl_label = "Image"
@@ -156,6 +176,8 @@ class IMAGE_MT_image(Menu):
layout.operator("image.read_renderlayers")
+ layout.operator("image.save_dirty", text="Save All Images")
+
if ima:
if not show_render:
layout.operator("image.replace")
@@ -382,7 +404,6 @@ class IMAGE_HT_header(Header):
mode = sima.mode
show_render = sima.show_render
- # show_paint = sima.show_paint
show_uvedit = sima.show_uvedit
show_maskedit = sima.show_maskedit
@@ -401,8 +422,7 @@ class IMAGE_HT_header(Header):
row = layout.row()
row.template_ID(sima, "mask", new="mask.new")
- if show_uvedit or show_maskedit:
- layout.prop(sima, "pivot_point", icon_only=True)
+ layout.prop(sima, "pivot_point", icon_only=True)
# uv editing
if show_uvedit:
@@ -462,6 +482,7 @@ class MASK_MT_editor_menus(Menu):
show_uvedit = sima.show_uvedit
show_maskedit = sima.show_maskedit
+ show_paint = sima.show_paint
layout.menu("IMAGE_MT_view")
@@ -469,6 +490,8 @@ class MASK_MT_editor_menus(Menu):
layout.menu("IMAGE_MT_select")
if show_maskedit:
layout.menu("MASK_MT_select")
+ if show_paint:
+ layout.menu("IMAGE_MT_brush")
if ima and ima.is_dirty:
layout.menu("IMAGE_MT_image", text="Image*")
@@ -658,49 +681,27 @@ class IMAGE_PT_tools_transform_uvs(Panel, UVToolsPanel):
col.operator("transform.shear")
-class IMAGE_PT_paint(Panel, ImagePaintPanel):
+class IMAGE_PT_paint(Panel, BrushButtonsPanel):
bl_label = "Paint"
-
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return sima.show_paint
+ bl_category = "Tools"
def draw(self, context):
layout = self.layout
- toolsettings = context.tool_settings.image_paint
- brush = toolsettings.brush
+ settings = context.tool_settings.image_paint
+ brush = settings.brush
col = layout.column()
- col.template_ID_preview(toolsettings, "brush", new="brush.add", rows=2, cols=6)
+ col.template_ID_preview(settings, "brush", new="brush.add", rows=2, cols=6)
if brush:
- col = layout.column()
-
- if brush.image_tool == 'DRAW' and brush.blend not in ('ERASE_ALPHA', 'ADD_ALPHA'):
- col.template_color_picker(brush, "color", value_slider=True)
- col.prop(brush, "color", text="")
-
- row = col.row(align=True)
- self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
- self.prop_unified_size(row, context, brush, "use_pressure_size")
-
- row = col.row(align=True)
- self.prop_unified_strength(row, context, brush, "strength", slider=True, text="Strength")
- self.prop_unified_strength(row, context, brush, "use_pressure_strength")
-
- col.prop(brush, "blend", text="Blend")
-
- if brush.image_tool == 'CLONE':
- col.separator()
- col.prop(brush, "clone_image", text="Image")
- col.prop(brush, "clone_alpha", text="Alpha")
+ brush_texpaint_common(self, context, layout, brush, settings)
class IMAGE_PT_tools_brush_overlay(BrushButtonsPanel, Panel):
bl_label = "Overlay"
bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Options"
def draw(self, context):
layout = self.layout
@@ -754,6 +755,7 @@ class IMAGE_PT_tools_brush_overlay(BrushButtonsPanel, Panel):
class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
bl_label = "Texture"
bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Tools"
def draw(self, context):
layout = self.layout
@@ -770,6 +772,7 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel):
bl_label = "Texture Mask"
bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Tools"
def draw(self, context):
layout = self.layout
@@ -786,6 +789,7 @@ class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel):
class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, Panel):
bl_label = "Tool"
bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Options"
def draw(self, context):
layout = self.layout
@@ -804,6 +808,7 @@ class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, Panel):
class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
bl_label = "Paint Stroke"
bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Tools"
def draw(self, context):
layout = self.layout
@@ -828,10 +833,19 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
if brush.use_space:
col.separator()
row = col.row(align=True)
- row.active = brush.use_space
row.prop(brush, "spacing", text="Spacing")
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
+ if brush.use_line or brush.use_curve:
+ col.separator()
+ row = col.row(align=True)
+ row.prop(brush, "spacing", text="Spacing")
+
+ if brush.use_curve:
+ col.separator()
+ col.template_ID(brush, "paint_curve", new="paintcurve.new")
+ col.operator("paintcurve.draw")
+
col = layout.column()
col.separator()
@@ -846,25 +860,23 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
col = layout.column()
col.separator()
- col.prop(brush, "use_smooth_stroke")
+ if brush.brush_capabilities.has_smooth_stroke:
+ col.prop(brush, "use_smooth_stroke")
- sub = col.column()
- sub.active = brush.use_smooth_stroke
- sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
- sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
+ sub = col.column()
+ sub.active = brush.use_smooth_stroke
+ sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
+ sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
- col.separator()
+ col.separator()
col.prop(toolsettings, "input_samples")
- col.separator()
-
- col.prop(brush, "use_wrap")
-
class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
bl_label = "Paint Curve"
bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Tools"
def draw(self, context):
layout = self.layout
@@ -874,7 +886,8 @@ class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
layout.template_curve_mapping(brush, "curve")
- row = layout.row(align=True)
+ col = layout.column(align=True)
+ row = col.row(align=True)
row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
@@ -886,6 +899,7 @@ class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
class IMAGE_PT_tools_brush_appearance(BrushButtonsPanel, Panel):
bl_label = "Appearance"
bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Options"
def draw(self, context):
layout = self.layout
@@ -912,6 +926,30 @@ class IMAGE_PT_tools_brush_appearance(BrushButtonsPanel, Panel):
sub.prop(brush, "icon_filepath", text="")
+class IMAGE_PT_tools_paint_options(BrushButtonsPanel, Panel):
+ bl_label = "Image Paint"
+ bl_category = "Options"
+
+ def draw(self, context):
+ layout = self.layout
+
+ toolsettings = context.tool_settings
+ brush = toolsettings.image_paint.brush
+
+ ups = toolsettings.unified_paint_settings
+
+ col = layout.column(align=True)
+
+ col.prop(brush, "use_wrap")
+ col.separator()
+
+ col.label(text="Unified Settings:")
+ row = col.row()
+ row.prop(ups, "use_unified_size", text="Size")
+ row.prop(ups, "use_unified_strength", text="Strength")
+ col.prop(ups, "use_unified_color", text="Color")
+
+
class IMAGE_UV_sculpt_curve(Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
@@ -1032,7 +1070,7 @@ class IMAGE_PT_view_waveform(Panel):
layout.template_waveform(sima, "scopes")
row = layout.split(percentage=0.75)
row.prop(sima.scopes, "waveform_alpha")
- row.prop(sima.scopes, "waveform_mode", icon_only=True)
+ row.prop(sima.scopes, "waveform_mode", text="")
class IMAGE_PT_view_vectorscope(Panel):
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index ddb83310fe8..67b2bbe1905 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -57,11 +57,9 @@ class INFO_HT_header(Header):
row = layout.row(align=True)
if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False:
- layout.operator_context = 'EXEC_DEFAULT'
row.label("Auto-run disabled: %s" % bpy.app.autoexec_fail_message, icon='ERROR')
if bpy.data.is_saved:
- props = row.operator("wm.open_mainfile", icon='SCREEN_BACK', text="Reload Trusted")
- props.filepath = bpy.data.filepath
+ props = row.operator("wm.revert_mainfile", icon='SCREEN_BACK', text="Reload Trusted")
props.use_scripts = True
row.operator("script.autoexec_warn_clear", text="Ignore")
@@ -129,10 +127,8 @@ class INFO_MT_file(Menu):
layout.separator()
layout.operator_context = 'INVOKE_AREA'
- layout.operator("wm.link_append", text="Link", icon='LINK_BLEND')
- props = layout.operator("wm.link_append", text="Append", icon='APPEND_BLEND')
- props.link = False
- props.instance_groups = False
+ layout.operator("wm.link", text="Link", icon='LINK_BLEND')
+ layout.operator("wm.append", text="Append", icon='APPEND_BLEND')
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 959043f7931..e8914a3e9b0 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -67,6 +67,16 @@ class NODE_HT_header(Header):
if snode_id:
row.prop(snode_id, "use_nodes")
+ if scene.render.use_shading_nodes and snode.shader_type == 'LINESTYLE':
+ rl = context.scene.render.layers.active
+ lineset = rl.freestyle_settings.linesets.active
+ if lineset is not None:
+ row = layout.row()
+ row.enabled = not snode.pin
+ row.template_ID(lineset, "linestyle", new="scene.freestyle_linestyle_new")
+ if snode_id:
+ row.prop(snode_id, "use_nodes")
+
elif snode.tree_type == 'TextureNodeTree':
layout.prop(snode, "texture_type", text="", expand=True)
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index b77078bf5d4..17e37f17974 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -59,12 +59,17 @@ class SEQUENCER_HT_header(Header):
layout = self.layout
st = context.space_data
+ scene = context.scene
row = layout.row(align=True)
row.template_header()
SEQUENCER_MT_editor_menus.draw_collapsible(context, layout)
+ row = layout.row(align=True)
+ row.prop(scene, "use_preview_range", text="", toggle=True)
+ row.prop(scene, "lock_frame_selection_to_range", text="", toggle=True)
+
layout.prop(st, "view_type", expand=True, text="")
if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
@@ -122,6 +127,7 @@ class SEQUENCER_MT_editor_menus(Menu):
layout.menu("SEQUENCER_MT_select")
layout.menu("SEQUENCER_MT_marker")
layout.menu("SEQUENCER_MT_add")
+ layout.menu("SEQUENCER_MT_frame")
layout.menu("SEQUENCER_MT_strip")
@@ -160,14 +166,14 @@ class SEQUENCER_MT_view(Menu):
if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
layout.operator_context = 'INVOKE_REGION_PREVIEW'
layout.operator("sequencer.view_all_preview", text="Fit preview in window")
-
+
layout.separator()
-
+
ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
for a, b in ratios:
layout.operator("sequencer.view_zoom_ratio", text=iface_("Zoom %d:%d") % (a, b), translate=False).ratio = a / b
-
+
layout.separator()
layout.operator_context = 'INVOKE_DEFAULT'
@@ -203,6 +209,13 @@ class SEQUENCER_MT_select(Menu):
layout.operator("sequencer.select_active_side", text="Strips to the Left").side = 'LEFT'
layout.operator("sequencer.select_active_side", text="Strips to the Right").side = 'RIGHT'
+ op = layout.operator("sequencer.select", text="All strips to the Left")
+ op.left_right = 'LEFT'
+ op.linked_time = True
+ op = layout.operator("sequencer.select", text="All strips to the Right")
+ op.left_right = 'RIGHT'
+ op.linked_time = True
+
layout.separator()
layout.operator("sequencer.select_handles", text="Surrounding Handles").side = 'BOTH'
layout.operator("sequencer.select_handles", text="Left Handle").side = 'LEFT'
@@ -237,6 +250,15 @@ class SEQUENCER_MT_change(Menu):
layout.operator("sequencer.change_path", text="Path/Files")
+class SEQUENCER_MT_frame(Menu):
+ bl_label = "Frame"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("anim.previewrange_clear")
+ layout.operator("anim.previewrange_set")
+
class SEQUENCER_MT_add(Menu):
bl_label = "Add"
@@ -284,6 +306,7 @@ class SEQUENCER_MT_add_effect(Menu):
layout.operator("sequencer.effect_strip_add", text="Alpha Under").type = 'ALPHA_UNDER'
layout.operator("sequencer.effect_strip_add", text="Cross").type = 'CROSS'
layout.operator("sequencer.effect_strip_add", text="Gamma Cross").type = 'GAMMA_CROSS'
+ layout.operator("sequencer.effect_strip_add", text="Gaussian Blur").type = 'GAUSSIAN_BLUR'
layout.operator("sequencer.effect_strip_add", text="Multiply").type = 'MULTIPLY'
layout.operator("sequencer.effect_strip_add", text="Over Drop").type = 'OVER_DROP'
layout.operator("sequencer.effect_strip_add", text="Wipe").type = 'WIPE'
@@ -490,7 +513,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
return strip.type in {'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED',
- 'MULTICAM'}
+ 'MULTICAM', 'GAUSSIAN_BLUR'}
def draw(self, context):
layout = self.layout
@@ -588,6 +611,9 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
col.prop(strip, "use_default_fade", "Default fade")
if not strip.use_default_fade:
col.prop(strip, "effect_fader", text="Effect fader")
+ elif strip.type == 'GAUSSIAN_BLUR':
+ col.prop(strip, "size_x")
+ col.prop(strip, "size_y")
class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index c96b8fd568e..cfb147b3566 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -176,8 +176,11 @@ class TIME_MT_frame(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("time.start_frame_set")
+ layout.operator("anim.previewrange_clear")
+ layout.operator("anim.previewrange_set")
+ layout.separator()
layout.operator("time.end_frame_set")
+ layout.operator("time.start_frame_set")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index cba6f065a6f..999e41e17f7 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -217,6 +217,13 @@ class USERPREF_PT_interface(Panel):
sub.prop(view, "open_sublevel_delay", text="Sub Level")
col.separator()
+ col.label(text="Pie Menus:")
+ sub = col.column(align=True)
+ sub.prop(view, "pie_animation_timeout")
+ sub.prop(view, "pie_initial_timeout")
+ sub.prop(view, "pie_menu_radius")
+ sub.prop(view, "pie_menu_threshold")
+ col.separator()
col.separator()
col.separator()
@@ -417,6 +424,12 @@ class USERPREF_PT_system(Panel):
col.prop(system, "use_gpu_mipmap")
col.prop(system, "use_16bit_textures")
+
+ if system.is_occlusion_query_supported():
+ col.separator()
+ col.label(text="Selection")
+ col.prop(system, "select_method", text="")
+
col.separator()
col.label(text="Anisotropic Filtering")
@@ -675,6 +688,9 @@ class USERPREF_PT_theme(Panel):
col.label(text="Menu:")
self._theme_widget_style(col, ui.wcol_menu)
+ col.label(text="Pie Menu:")
+ self._theme_widget_style(col, ui.wcol_pie_menu)
+
col.label(text="Pulldown:")
self._theme_widget_style(col, ui.wcol_pulldown)
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 6f0b97fcb4b..61d359ebdac 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2223,7 +2223,7 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
layout.separator()
- if with_freestyle and not scene.render.use_shading_nodes:
+ if with_freestyle:
layout.operator("mesh.mark_freestyle_edge").clear = False
layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
layout.separator()
@@ -2266,11 +2266,12 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout.operator("mesh.inset")
layout.operator("mesh.bevel").vertex_only = False
layout.operator("mesh.solidify")
+ layout.operator("mesh.intersect")
layout.operator("mesh.wireframe")
layout.separator()
- if with_freestyle and not scene.render.use_shading_nodes:
+ if with_freestyle:
layout.operator("mesh.mark_freestyle_face").clear = False
layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True
layout.separator()
@@ -2278,6 +2279,7 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout.operator("mesh.poke")
layout.operator("mesh.quads_convert_to_tris")
layout.operator("mesh.tris_convert_to_quads")
+ layout.operator("mesh.face_split_by_edges")
layout.separator()
@@ -2933,7 +2935,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
col.prop(mesh, "show_edge_seams", text="Seams")
col.prop(mesh, "show_edge_sharp", text="Sharp", text_ctxt=i18n_contexts.plural)
col.prop(mesh, "show_edge_bevel_weight", text="Bevel")
- if with_freestyle and not scene.render.use_shading_nodes:
+ if with_freestyle:
col.prop(mesh, "show_freestyle_edge_marks", text="Edge Marks")
col.prop(mesh, "show_freestyle_face_marks", text="Face Marks")
@@ -2944,7 +2946,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
row = col.row(align=True)
row.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
- row.prop(mesh, "show_normal_loop", text="", icon='VERTEXSEL')
+ row.prop(mesh, "show_normal_loop", text="", icon='LOOPSEL')
row.prop(mesh, "show_normal_face", text="", icon='FACESEL')
sub = row.row(align=True)
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 0f2c04d1cdc..6b0c5b1e993 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -18,11 +18,12 @@
# <pep8 compliant>
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import Menu, Panel, UIList
from bl_ui.properties_grease_pencil_common import GreasePencilPanel
from bl_ui.properties_paint_common import (
UnifiedPaintPanel,
brush_texture_settings,
+ brush_texpaint_common,
brush_mask_texture_settings,
)
@@ -34,14 +35,6 @@ class View3DPanel():
# **************** standard tool clusters ******************
-# History/Repeat tools
-def draw_repeat_tools(context, layout):
- col = layout.column(align=True)
- col.label(text="Repeat:")
- col.operator("screen.repeat_last")
- col.operator("screen.repeat_history", text="History...")
-
-
# Keyframing tools
def draw_keyframing_tools(context, layout):
col = layout.column(align=True)
@@ -105,24 +98,6 @@ class VIEW3D_PT_tools_object(View3DPanel, Panel):
row.operator("object.shade_flat", text="Flat")
-class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
- bl_category = "Tools"
- bl_context = "objectmode"
- bl_label = "History"
- bl_options = {'DEFAULT_CLOSED'}
-
- def draw(self, context):
- layout = self.layout
-
- col = layout.column(align=True)
- row = col.row(align=True)
- row.operator("ed.undo")
- row.operator("ed.redo")
- col.operator("ed.undo_history")
-
- draw_repeat_tools(context, layout)
-
-
class VIEW3D_PT_tools_add_object(View3DPanel, Panel):
bl_category = "Create"
bl_context = "objectmode"
@@ -361,7 +336,6 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
col.operator_menu_enum("mesh.merge", "type")
col.operator("mesh.remove_doubles")
- draw_repeat_tools(context, layout)
class VIEW3D_PT_tools_meshweight(View3DPanel, Panel):
bl_category = "Tools"
@@ -388,6 +362,7 @@ class VIEW3D_PT_tools_meshweight(View3DPanel, Panel):
layout = self.layout
self.draw_generic(layout)
+
class VIEW3D_PT_tools_add_mesh_edit(View3DPanel, Panel):
bl_category = "Create"
bl_context = "mesh_edit"
@@ -538,8 +513,6 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
col.operator("curve.smooth")
col.operator("object.vertex_random")
- draw_repeat_tools(context, layout)
-
class VIEW3D_PT_tools_add_curve_edit(View3DPanel, Panel):
bl_category = "Create"
@@ -594,8 +567,6 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel):
col.label(text="Deform:")
col.operator("object.vertex_random")
- draw_repeat_tools(context, layout)
-
class VIEW3D_PT_tools_add_surface_edit(View3DPanel, Panel):
bl_category = "Create"
@@ -632,8 +603,6 @@ class VIEW3D_PT_tools_textedit(View3DPanel, Panel):
col.operator("font.style_toggle", text="Italic").style = 'ITALIC'
col.operator("font.style_toggle", text="Underline").style = 'UNDERLINE'
- draw_repeat_tools(context, layout)
-
# ********** default tools for editmode_armature ****************
@@ -675,8 +644,6 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
col.label(text="Deform:")
col.operator("object.vertex_random")
- draw_repeat_tools(context, layout)
-
class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
bl_category = "Options"
@@ -710,8 +677,6 @@ class VIEW3D_PT_tools_mballedit(View3DPanel, Panel):
col.label(text="Deform:")
col.operator("object.vertex_random")
- draw_repeat_tools(context, layout)
-
class VIEW3D_PT_tools_add_mball_edit(View3DPanel, Panel):
bl_category = "Create"
@@ -750,8 +715,6 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel):
col.label(text="Deform:")
col.operator("object.vertex_random")
- draw_repeat_tools(context, layout)
-
# ********** default tools for pose-mode ****************
@@ -794,8 +757,6 @@ class VIEW3D_PT_tools_posemode(View3DPanel, Panel):
row.operator("pose.paths_calculate", text="Calculate")
row.operator("pose.paths_clear", text="Clear")
- draw_repeat_tools(context, layout)
-
class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
bl_category = "Options"
@@ -979,25 +940,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
# Texture Paint Mode #
elif context.image_paint_object and brush:
- col = layout.column()
-
- if brush.image_tool == 'DRAW' and brush.blend not in ('ERASE_ALPHA', 'ADD_ALPHA'):
- col.template_color_picker(brush, "color", value_slider=True)
- col.prop(brush, "color", text="")
-
- row = col.row(align=True)
- self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
- self.prop_unified_size(row, context, brush, "use_pressure_size")
-
- row = col.row(align=True)
- self.prop_unified_strength(row, context, brush, "strength", text="Strength")
- self.prop_unified_strength(row, context, brush, "use_pressure_strength")
-
- col.prop(brush, "blend", text="Blend")
-
- col = layout.column()
- col.active = (brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'})
- col.prop(brush, "use_alpha")
+ brush_texpaint_common(self, context, layout, brush, settings, True)
# Weight Paint Mode #
elif context.weight_paint_object and brush:
@@ -1024,9 +967,12 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
# Vertex Paint Mode #
elif context.vertex_paint_object and brush:
col = layout.column()
- col.template_color_picker(brush, "color", value_slider=True)
- col.prop(brush, "color", text="")
+ self.prop_unified_color_picker(col, context, brush, "color", value_slider=True)
+ if settings.palette:
+ col.template_palette(settings, "palette", color=True)
+ self.prop_unified_color(col, context, brush, "color", text="")
+ col.separator()
row = col.row(align=True)
self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
self.prop_unified_size(row, context, brush, "use_pressure_size")
@@ -1036,12 +982,128 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
# XXX - TODO
- #row = col.row(align=True)
- #row.prop(brush, "jitter", slider=True)
- #row.prop(brush, "use_pressure_jitter", toggle=True, text="")
-
+ # row = col.row(align=True)
+ # row.prop(brush, "jitter", slider=True)
+ # row.prop(brush, "use_pressure_jitter", toggle=True, text="")
+ col.separator()
col.prop(brush, "vertex_tool", text="Blend")
+ col.separator()
+ col.template_ID(settings, "palette", new="palette.new")
+
+
+class TEXTURE_UL_texpaintslots(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ mat = data
+
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ layout.prop(item, "name", text="", emboss=False, icon_value=icon)
+ if (not mat.use_nodes) and (context.scene.render.engine == 'BLENDER_RENDER'):
+ mtex_index = mat.texture_paint_slots[index].index
+ layout.prop(mat, "use_textures", text="", index=mtex_index)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="")
+
+
+class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
+ bl_context = "imagepaint"
+ bl_label = "Slots"
+ bl_category = "Slots"
+
+ @classmethod
+ def poll(cls, context):
+ brush = context.tool_settings.image_paint.brush
+ ob = context.active_object
+ return (brush is not None and ob is not None)
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = context.tool_settings.image_paint
+ # brush = settings.brush
+
+ ob = context.active_object
+ col = layout.column()
+
+ col.label("Painting Mode")
+ col.prop(settings, "mode", text = "")
+ col.separator()
+
+ if settings.mode == 'MATERIAL':
+ if len(ob.material_slots) > 1:
+ col.label("Materials")
+ col.template_list("MATERIAL_UL_matslots", "layers",
+ ob, "material_slots",
+ ob, "active_material_index", rows=2)
+
+ mat = ob.active_material
+ if mat:
+ col.label("Available Paint Slots")
+ col.template_list("TEXTURE_UL_texpaintslots", "",
+ mat, "texture_paint_images",
+ mat, "paint_active_slot", rows=2)
+
+ if (not mat.use_nodes) and (context.scene.render.engine == 'BLENDER_RENDER'):
+ row = col.row(align=True)
+ row.operator_menu_enum("paint.add_texture_paint_slot", "type")
+ row.operator("paint.delete_texture_paint_slot", text="", icon='X')
+
+ if mat.texture_paint_slots:
+ slot = mat.texture_paint_slots[mat.paint_active_slot]
+
+ col.prop(mat.texture_slots[slot.index], "blend_type")
+ col.separator()
+ col.label("UV Map")
+ col.prop_search(slot, "uv_layer", ob.data, "uv_textures", text="")
+
+ elif settings.mode == 'IMAGE':
+ col.template_ID(settings, "canvas")
+
+ col.separator()
+ col.operator("image.save_dirty", text="Save All Images")
+
+
+
+class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
+ bl_context = "imagepaint"
+ bl_label = "Stencil"
+ bl_category = "Slots"
+
+ @classmethod
+ def poll(cls, context):
+ brush = context.tool_settings.image_paint.brush
+ ob = context.active_object
+ return (brush is not None and ob is not None)
+
+ def draw_header(self, context):
+ ipaint = context.tool_settings.image_paint
+ self.layout.prop(ipaint, "use_stencil_layer", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ toolsettings = context.tool_settings
+ ipaint = toolsettings.image_paint
+ ob = context.active_object
+ mesh = ob.data
+
+ col = layout.column()
+ col.active = ipaint.use_stencil_layer
+
+ stencil_text = mesh.uv_texture_stencil.name if mesh.uv_texture_stencil else ""
+ col.label("UV Map")
+ col.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text, translate=False)
+
+ col.label("Image")
+ row = col.row(align=True)
+ row.template_ID(ipaint, "stencil_image")
+
+ col.label("Visualization")
+ row = col.row(align=True)
+ row.prop(ipaint, "stencil_color", text="")
+ row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
+
class VIEW3D_PT_tools_brush_overlay(Panel, View3DPaintPanel):
bl_category = "Options"
@@ -1194,10 +1256,19 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
if brush.use_space:
col.separator()
row = col.row(align=True)
- row.active = brush.use_space
row.prop(brush, "spacing", text="Spacing")
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
+ if brush.use_line or brush.use_curve:
+ col.separator()
+ row = col.row(align=True)
+ row.prop(brush, "spacing", text="Spacing")
+
+ if brush.use_curve:
+ col.separator()
+ col.template_ID(brush, "paint_curve", new="paintcurve.new")
+ col.operator("paintcurve.draw")
+
if context.sculpt_object:
if brush.sculpt_capabilities.has_jitter:
col.separator()
@@ -1234,12 +1305,13 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
col = layout.column()
col.separator()
- col.prop(brush, "use_smooth_stroke")
+ if brush.brush_capabilities.has_smooth_stroke:
+ col.prop(brush, "use_smooth_stroke")
- sub = col.column()
- sub.active = brush.use_smooth_stroke
- sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
- sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
+ sub = col.column()
+ sub.active = brush.use_smooth_stroke
+ sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
+ sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
layout.prop(settings, "input_samples")
@@ -1263,7 +1335,8 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
layout.template_curve_mapping(brush, "curve", brush=True)
- row = layout.row(align=True)
+ col = layout.column(align=True)
+ row = col.row(align=True)
row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
@@ -1300,8 +1373,8 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
sub.active = (brush and brush.sculpt_tool != 'MASK')
if (sculpt.detail_type_method == 'CONSTANT'):
row = sub.row(align=True)
- row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
row.prop(sculpt, "constant_detail")
+ row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
else:
sub.prop(sculpt, "detail_size")
sub.prop(sculpt, "detail_refine_method", text="")
@@ -1327,7 +1400,7 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
def draw(self, context):
layout = self.layout
- scene = context.scene
+ # scene = context.scene
toolsettings = context.tool_settings
sculpt = toolsettings.sculpt
@@ -1493,7 +1566,7 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
col = layout.column()
row = col.row()
- #col.prop(vpaint, "mode", text="")
+ # col.prop(vpaint, "mode", text="")
row.prop(vpaint, "use_normal")
col.prop(vpaint, "use_spray")
@@ -1528,10 +1601,9 @@ class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel):
col.row().prop(ipaint, "screen_grab_size", text="")
col.operator("paint.project_image", text="Apply Camera Image")
- col.operator("image.save_dirty", text="Save All Edited")
-class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
+class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel):
bl_category = "Options"
bl_context = "imagepaint"
bl_label = "Project Paint"
@@ -1544,13 +1616,11 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
def draw(self, context):
layout = self.layout
- ob = context.active_object
- mesh = ob.data
toolsettings = context.tool_settings
ipaint = toolsettings.image_paint
- settings = toolsettings.image_paint
col = layout.column()
+
col.prop(ipaint, "use_occlude")
col.prop(ipaint, "use_backface_culling")
@@ -1561,23 +1631,8 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
sub.active = (ipaint.use_normal_falloff)
sub.prop(ipaint, "normal_angle", text="")
- split = layout.split()
-
- split.prop(ipaint, "use_stencil_layer", text="Stencil")
-
- row = split.row()
- row.active = (ipaint.use_stencil_layer)
- stencil_text = mesh.uv_texture_stencil.name if mesh.uv_texture_stencil else ""
- row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text, translate=False)
- row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
-
- col = layout.column()
- col.active = (settings.brush.image_tool == 'CLONE')
- col.prop(ipaint, "use_clone_layer", text="Clone from UV map")
- clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else ""
- col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text, translate=False)
-
layout.prop(ipaint, "seam_bleed")
+ self.unified_paint_settings(layout, context)
class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
@@ -1595,18 +1650,6 @@ class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
self.unified_paint_settings(col, context)
-class VIEW3D_MT_tools_projectpaint_clone(Menu):
- bl_label = "Clone Layer"
-
- def draw(self, context):
- layout = self.layout
-
- for i, tex in enumerate(context.active_object.data.uv_textures):
- props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
- props.data_path = "active_object.data.uv_texture_clone_index"
- props.value = i
-
-
class VIEW3D_MT_tools_projectpaint_stencil(Menu):
bl_label = "Mask Layer"
@@ -1694,5 +1737,30 @@ class VIEW3D_PT_tools_grease_pencil(GreasePencilPanel, Panel):
bl_category = "Grease Pencil"
+# Note: moved here so that it's always in last position in 'Tools' panels!
+class VIEW3D_PT_tools_history(View3DPanel, Panel):
+ bl_category = "Tools"
+ # No bl_context, we are always available!
+ bl_label = "History"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ obj = context.object
+
+ col = layout.column(align=True)
+ row = col.row(align=True)
+ row.operator("ed.undo")
+ row.operator("ed.redo")
+ if obj is None or obj.mode not in {'SCULPT'}:
+ # Sculpt mode does not generate an undo menu it seems...
+ col.operator("ed.undo_history")
+
+ col = layout.column(align=True)
+ col.label(text="Repeat:")
+ col.operator("screen.repeat_last")
+ col.operator("screen.repeat_history", text="History...")
+
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 0a90b9f01f8..5dccda789e0 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -105,6 +105,13 @@ def group_input_output_item_poll(context):
return False
+# only show input/output nodes when editing line style node trees
+def line_style_shader_nodes_poll(context):
+ snode = context.space_data
+ return (snode.tree_type == 'ShaderNodeTree' and
+ snode.shader_type == 'LINESTYLE')
+
+
# All standard node categories currently used in nodes.
shader_node_categories = [
@@ -169,12 +176,14 @@ shader_node_categories = [
NodeItem("ShaderNodeParticleInfo"),
NodeItem("ShaderNodeCameraData"),
NodeItem("ShaderNodeUVMap"),
+ NodeItem("ShaderNodeUVAlongStroke", poll=line_style_shader_nodes_poll),
NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
]),
ShaderNewNodeCategory("SH_NEW_OUTPUT", "Output", items=[
NodeItem("ShaderNodeOutputMaterial"),
NodeItem("ShaderNodeOutputLamp"),
NodeItem("ShaderNodeOutputWorld"),
+ NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll),
NodeItem("NodeGroupOutput", poll=group_input_output_item_poll),
]),
ShaderNewNodeCategory("SH_NEW_SHADER", "Shader", items=[
@@ -318,6 +327,7 @@ compositor_node_categories = [
NodeItem("CompositorNodeInpaint"),
NodeItem("CompositorNodeDBlur"),
NodeItem("CompositorNodePixelate"),
+ NodeItem("CompositorNodeSunBeams"),
]),
CompositorNodeCategory("CMP_OP_VECTOR", "Vector", items=[
NodeItem("CompositorNodeNormal"),
diff --git a/release/scripts/templates_osl/fresnel_conductive.osl b/release/scripts/templates_osl/fresnel_conductive.osl
new file mode 100644
index 00000000000..c197656eaee
--- /dev/null
+++ b/release/scripts/templates_osl/fresnel_conductive.osl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011-2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+color fresnel_conductor(float cosi, color eta, color k)
+{
+ color cosi2 = color(cosi*cosi);
+ color one = color(1, 1, 1);
+ color tmp_f = eta * eta + k * k;
+ color tmp = tmp_f * cosi2;
+ color Rparl2 = (tmp - (2.0 * eta * cosi) + one) /
+ (tmp + (2.0 * eta * cosi) + one);
+ color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) /
+ (tmp_f + (2.0 * eta * cosi) + cosi2);
+ return (Rparl2 + Rperp2) * 0.5;
+}
+
+shader node_fresnel_conductive(
+ color n = color(0.084136, 0.410708, 1.472421),
+ color k = color(4.018579, 2.363371, 1.607574),
+ normal Normal = N,
+ output color Color = color(0.8, 0.8, 0.8))
+{
+ float cosi = dot(I, Normal);
+ Color = fresnel_conductor(cosi, n, k);
+}
diff --git a/release/scripts/templates_py/ui_pie_menu.py b/release/scripts/templates_py/ui_pie_menu.py
new file mode 100644
index 00000000000..87500b682d6
--- /dev/null
+++ b/release/scripts/templates_py/ui_pie_menu.py
@@ -0,0 +1,32 @@
+import bpy
+from bpy.types import Menu
+
+# spawn an edit mode selection pie (run while object is in edit mode to get a valid output)
+
+
+class VIEW3D_PIE_template(Menu):
+ # label is displayed at the center of the pie menu.
+ bl_label = "Select Mode"
+
+ def draw(self, context):
+ layout = self.layout
+
+ pie = layout.menu_pie()
+ # operator_enum will just spread all available options
+ # for the type enum of the operator on the pie
+ pie.operator_enum("mesh.select_mode", "type")
+
+
+def register():
+ bpy.utils.register_class(VIEW3D_PIE_template)
+
+
+def unregister():
+ bpy.utils.unregister_class(VIEW3D_PIE_template)
+
+
+if __name__ == "__main__":
+ register()
+
+ bpy.ops.wm.call_menu_pie(name="VIEW3D_PIE_template")
+
diff --git a/release/text/readme.html b/release/text/readme.html
index 452293ad702..4d8b0bf24d2 100644
--- a/release/text/readme.html
+++ b/release/text/readme.html
@@ -20,18 +20,18 @@
</style>
</head>
<body>
-<p class="p1"><b>Blender 2.71</b></p>
+<p class="p1"><b>Blender 2.72</b></p>
<p class="p2"><br></p>
<p class="p3"><b>About</b></p>
<p class="p4">Welcome to Blender, the free, open source 3D application for modeling, animation, rendering, compositing, video editing and game creation. Blender is available for Linux, Mac OS X and Windows and has a large world-wide community.</p>
<p class="p4">Blender can be used freely for any purpose, including commercial use and distribution. It's free and open-source software, released under the GNU GPL licence. The entire source code is available on our website.</p>
<p class="p4">For more information, visit <a href="http://www.blender.org/"><span class="s1">blender.org</span></a>.</p>
<p class="p2"><br></p>
-<p class="p3"><b>2.71</b></p>
-<p class="p4">The Blender Foundation and online developer community is proud to present Blender 2.71. This release is the second official stable release of the Blender 2.7 series. <a href="http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.71"><span class="s1">More information about this release</span></a>.</p>
+<p class="p3"><b>2.72</b></p>
+<p class="p4">The Blender Foundation and online developer community is proud to present Blender 2.72. This release is the third official stable release of the Blender 2.7 series. <a href="http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72"><span class="s1">More information about this release</span></a>.</p>
<p class="p2"><br></p>
<p class="p3"><b>Bugs</b></p>
-<p class="p4">Although Blender 2.71 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help <span class="s2">→</span> Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
+<p class="p4">Although Blender 2.72 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help <span class="s2">→</span> Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
<p class="p2"><br></p>
<p class="p3"><b>Package Contents</b></p>
<p class="p4">The downloaded Blender package includes:</p>
@@ -55,7 +55,7 @@
<p class="p3"><b>Links</b></p>
<p class="p4">Users:</p>
<p class="p5"><span class="s3">General information <a href="http://www.blender.org/"><span class="s4">www.blender.org</span></a> <br>
-Full release log <a href="http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.71"><span class="s4">wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.71</span></a><br>
+Full release log <a href="http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72"><span class="s4">wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72</span></a><br>
Tutorials <a href="http://www.blender.org/support/tutorials/"><span class="s4">www.blender.org/support/tutorials/</span></a> <br>
Manual <a href="http://wiki.blender.org/index.php/Doc:2.6/Manual"><span class="s4">wiki.blender.org/index.php/Doc:2.6/Manual</span></a><br>
User Forum <a href="http://www.blenderartists.org/"><span class="s4">www.blenderartists.org</span></a><br>