Merge branch 'master' into cycles_disney_brdf

This commit is contained in:
2016-09-06 15:59:05 +02:00
49 changed files with 579 additions and 179 deletions

View File

@@ -245,7 +245,7 @@ if(WITH_BOOST)
set(Boost_USE_STATIC_LIBS ON)
endif()
set(Boost_USE_MULTITHREADED ON)
set(__boost_packages filesystem regex system thread date_time)
set(__boost_packages filesystem regex thread date_time)
if(WITH_CYCLES_OSL)
if(NOT (${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6"))
list(APPEND __boost_packages wave)
@@ -261,6 +261,7 @@ if(WITH_BOOST)
if(WITH_OPENVDB)
list(APPEND __boost_packages iostreams)
endif()
list(APPEND __boost_packages system)
find_package(Boost 1.48 COMPONENTS ${__boost_packages})
if(NOT Boost_FOUND)
# try to find non-multithreaded if -mt not found, this flag

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = "V2.7x"
PROJECT_NUMBER = "V2.8x"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@@ -0,0 +1,182 @@
#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Contributor(s): Bastien Montagne
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
"""
This is a helper script to generate Blender Python API documentation (using Sphinx), and update server data using rsync.
You'll need to specify your user login and password, obviously.
Example usage:
./sphinx_doc_update.py --mirror ../../../docs/remote_api_backup/ --source ../.. --blender ../../../build_cmake/bin/blender --user foobar --password barfoo
"""
import os
import shutil
import subprocess
import sys
import tempfile
import zipfile
DEFAULT_RSYNC_SERVER = "www.blender.org"
DEFAULT_RSYNC_ROOT = "/api/"
DEFAULT_SYMLINK_ROOT = "/data/www/vhosts/www.blender.org/api"
def argparse_create():
import argparse
global __doc__
# When --help or no args are given, print this help
usage_text = __doc__
parser = argparse.ArgumentParser(description=usage_text,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument(
"--mirror", dest="mirror_dir",
metavar='PATH', required=True,
help="Path to local rsync mirror of api doc server")
parser.add_argument(
"--source", dest="source_dir",
metavar='PATH', required=True,
help="Path to Blender git repository")
parser.add_argument(
"--blender", dest="blender",
metavar='PATH', required=True,
help="Path to Blender executable")
parser.add_argument(
"--rsync-server", dest="rsync_server", default=DEFAULT_RSYNC_SERVER,
metavar='RSYNCSERVER', type=str, required=False,
help=("rsync server address"))
parser.add_argument(
"--rsync-root", dest="rsync_root", default=DEFAULT_RSYNC_ROOT,
metavar='RSYNCROOT', type=str, required=False,
help=("Root path of API doc on rsync server"))
parser.add_argument(
"--user", dest="user",
metavar='USER', type=str, required=True,
help=("User to login on rsync server"))
parser.add_argument(
"--password", dest="password",
metavar='PASSWORD', type=str, required=True,
help=("Password to login on rsync server"))
return parser
def main():
# ----------
# Parse Args
args = argparse_create().parse_args()
rsync_base = "rsync://%s@%s:%s" % (args.user, args.rsync_server, args.rsync_root)
# I) Update local mirror using rsync.
rsync_mirror_cmd = ("rsync", "--delete-after", "-avzz", rsync_base, args.mirror_dir)
subprocess.run(rsync_mirror_cmd, env=dict(os.environ, RSYNC_PASSWORD=args.password))
with tempfile.TemporaryDirectory() as tmp_dir:
# II) Generate doc source in temp dir.
doc_gen_cmd = (args.blender, "--background", "-noaudio", "--factory-startup", "--python-exit-code", "1",
"--python", "%s/doc/python_api/sphinx_doc_gen.py" % args.source_dir, "--",
"--output", tmp_dir)
subprocess.run(doc_gen_cmd)
# III) Get Blender version info.
blenver = ""
getver_file = os.path.join(tmp_dir, "blendver.txt")
getver_script = (""
"import sys, bpy\n"
"with open(sys.argv[-1], 'w') as f:\n"
" f.write('%d_%d%s_release' % (bpy.app.version[0], bpy.app.version[1], bpy.app.version_char)\n"
" if bpy.app.version_cycle in {'rc', 'release'} else '%d_%d_%d' % bpy.app.version)\n")
get_ver_cmd = (args.blender, "--background", "-noaudio", "--factory-startup", "--python-exit-code", "1",
"--python-expr", getver_script, "--", getver_file)
subprocess.run(get_ver_cmd)
with open(getver_file) as f:
blenver = f.read()
os.remove(getver_file)
# IV) Build doc.
curr_dir = os.getcwd()
os.chdir(tmp_dir)
sphinx_cmd = ("sphinx-build", "-b", "html", "sphinx-in", "sphinx-out")
subprocess.run(sphinx_cmd)
shutil.rmtree(os.path.join("sphinx-out", ".doctrees"))
os.chdir(curr_dir)
# V) Cleanup existing matching dir in server mirror (if any), and copy new doc.
api_name = "blender_python_api_%s" % blenver
api_dir = os.path.join(args.mirror_dir, api_name)
if os.path.exists(api_dir):
shutil.rmtree(api_dir)
os.rename(os.path.join(tmp_dir, "sphinx-out"), api_dir)
# VI) Create zip archive.
zip_name = "blender_python_reference_%s" % blenver
zip_path = os.path.join(args.mirror_dir, zip_name)
with zipfile.ZipFile(zip_path, 'w') as zf:
for de in os.scandir(api_dir):
zf.write(de.path, arcname=os.path.join(zip_name, de.name))
os.rename(zip_path, os.path.join(api_dir, "%s.zip" % zip_name))
# VII) Create symlinks and html redirects.
#~ os.symlink(os.path.join(DEFAULT_SYMLINK_ROOT, api_name, "contents.html"), os.path.join(api_dir, "index.html"))
os.symlink("./contents.html", os.path.join(api_dir, "index.html"))
if blenver.endswith("release"):
symlink = os.path.join(args.mirror_dir, "blender_python_api_current")
os.remove(symlink)
os.symlink("./%s" % api_name, symlink)
with open(os.path.join(args.mirror_dir, "250PythonDoc/index.html"), 'w') as f:
f.write("<html><head><title>Redirecting...</title><meta http-equiv=\"REFRESH\""
"content=\"0;url=../%s/\"></head><body>Redirecting...</body></html>" % api_name)
else:
symlink = os.path.join(args.mirror_dir, "blender_python_api_master")
os.remove(symlink)
os.symlink("./%s" % api_name, symlink)
with open(os.path.join(args.mirror_dir, "blender_python_api/index.html"), 'w') as f:
f.write("<html><head><title>Redirecting...</title><meta http-equiv=\"REFRESH\""
"content=\"0;url=../%s/\"></head><body>Redirecting...</body></html>" % api_name)
# VIII) Upload (first do a dry-run so user can ensure everything is OK).
print("Doc generated in local mirror %s, please check it before uploading "
"(hit [Enter] to continue, [Ctrl-C] to exit):" % api_dir)
sys.stdin.read(1)
rsync_mirror_cmd = ("rsync", "--dry-run", "--delete-after", "-avzz", args.mirror_dir, rsync_base)
subprocess.run(rsync_mirror_cmd, env=dict(os.environ, RSYNC_PASSWORD=args.password))
print("Rsync upload simulated, please check every thing is OK (hit [Enter] to continue, [Ctrl-C] to exit):")
sys.stdin.read(1)
rsync_mirror_cmd = ("rsync", "--delete-after", "-avzz", args.mirror_dir, rsync_base)
subprocess.run(rsync_mirror_cmd, env=dict(os.environ, RSYNC_PASSWORD=args.password))
if __name__ == "__main__":
main()

View File

@@ -69,7 +69,7 @@ ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd,
# if __CUDA_ARCH__ >= 300
CUtexObject tex = kernel_tex_fetch(__bindless_mapping, desc.offset);
float f = kernel_tex_image_interp_3d_float(tex, P.x, P.y, P.z);
float4 r = make_float4(f, f, f, 1.0);
float4 r = make_float4(f, f, f, 1.0f);
# else
float4 r = volume_image_texture_3d(desc.offset, P.x, P.y, P.z);
# endif

View File

@@ -112,7 +112,7 @@ template<typename T> struct texture_image {
ccl_always_inline float4 read(uchar r)
{
float f = r*(1.0f/255.0f);
return make_float4(f, f, f, 1.0);
return make_float4(f, f, f, 1.0f);
}
ccl_always_inline float4 read(float r)

View File

@@ -296,7 +296,7 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
/* float, byte and half */
else {
float f = kernel_tex_image_interp_float(tex, x, y);
r = make_float4(f, f, f, 1.0);
r = make_float4(f, f, f, 1.0f);
}
# endif
#endif

View File

@@ -50,7 +50,7 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
r = kernel_tex_image_interp_3d_float4(tex, co.x, co.y, co.z);
else {
float f = kernel_tex_image_interp_3d_float(tex, co.x, co.y, co.z);
r = make_float4(f, f, f, 1.0);
r = make_float4(f, f, f, 1.0f);
}
# else /* __CUDA_ARCH__ >= 300 */
r = volume_image_texture_3d(id, co.x, co.y, co.z);

View File

@@ -1650,10 +1650,10 @@ void MeshManager::device_update_displacement_images(Device *device,
foreach(Mesh *mesh, scene->meshes) {
if(mesh->need_update) {
foreach(Shader *shader, mesh->used_shaders) {
if(shader->graph_bump == NULL) {
if(!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
continue;
}
foreach(ShaderNode* node, shader->graph_bump->nodes) {
foreach(ShaderNode* node, shader->graph->nodes) {
if(node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
continue;
}

View File

@@ -798,6 +798,7 @@ class CameraNode : public ShaderNode {
public:
SHADER_NODE_CLASS(CameraNode)
bool has_spatial_varying() { return true; }
virtual int get_group() { return NODE_GROUP_LEVEL_2; }
};
class FresnelNode : public ShaderNode {

View File

@@ -838,7 +838,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
case KeyRelease:
{
XKeyEvent *xke = &(xe->xkey);
KeySym key_sym;
KeySym key_sym = XK_VoidSymbol;
KeySym key_sym_str;
char ascii;
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
@@ -870,26 +870,30 @@ GHOST_SystemX11::processEvent(XEvent *xe)
*
* To address this, we:
*
* - Try to get a 'number' key_sym using XLookupKeysym (with or without shift modifier).
* - Try to get a 'number' key_sym using XLookupKeysym (with virtual shift modifier),
* in a very restrictive set of cases.
* - Fallback to XLookupString to get a key_sym from active user-defined keymap.
*
* Note that this enforces users to use an ascii-compatible keymap with Blender - but at least it gives
* predictable and consistent results.
* Note that:
* - This effectively 'lock' main number keys to always output number events (except when using alt-gr).
* - This enforces users to use an ascii-compatible keymap with Blender - but at least it gives
* predictable and consistent results.
*
* Also, note that nothing in XLib sources [1] makes it obvious why those two functions give different
* key_sym results...
*
* [1] http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/KeyBind.c
*/
if ((xke->keycode >= 10 && xke->keycode < 20)) {
/* Mode_switch 'modifier' is AltGr - when this one or Shift are enabled, we do not want to apply
* that 'forced number' hack. */
const unsigned int mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch);
const unsigned int number_hack_forbidden_kmods_mask = mode_switch_mask | ShiftMask;
if ((xke->keycode >= 10 && xke->keycode < 20) && ((xke->state & number_hack_forbidden_kmods_mask) == 0)) {
key_sym = XLookupKeysym(xke, ShiftMask);
if (!((key_sym >= XK_0) && (key_sym <= XK_9))) {
key_sym = XLookupKeysym(xke, 0);
key_sym = XK_VoidSymbol;
}
}
else {
key_sym = XLookupKeysym(xke, 0);
}
if (!XLookupString(xke, &ascii, 1, &key_sym_str, NULL)) {
ascii = '\0';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 794 KiB

After

Width:  |  Height:  |  Size: 965 KiB

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Use this script to generate splash.png from splash_2x.png.
# Supposed to give best quality image.
#
# Based on ImageMagic documentation, which is interesting
# to read anyway:
#
# http://www.imagemagick.org/Usage/filter
# http://www.imagemagick.org/Usage/filter/nicolas/
convert \
splash_2x.png \
-colorspace RGB \
-filter Cosine \
-resize 50% \
-colorspace sRGB \
splash.png

View File

@@ -411,6 +411,20 @@ class VIEW3D_MT_uv_map(Menu):
layout.operator("uv.reset")
class VIEW3D_MT_edit_proportional(Menu):
bl_label = "Proportional Editing"
def draw(self, context):
layout = self.layout
layout.props_enum(context.tool_settings, "proportional_edit")
layout.separator()
layout.label("Falloff:")
layout.props_enum(context.tool_settings, "proportional_edit_falloff")
# ********** View menus **********
@@ -2311,8 +2325,7 @@ class VIEW3D_MT_edit_mesh(Menu):
layout.separator()
layout.prop(toolsettings, "use_mesh_automerge")
layout.prop_menu_enum(toolsettings, "proportional_edit")
layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
layout.menu("VIEW3D_MT_edit_proportional")
layout.separator()
@@ -2427,6 +2440,8 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
with_bullet = bpy.app.build_options.bullet
layout.operator("mesh.merge")
layout.operator("mesh.rip_move")
layout.operator("mesh.rip_move_fill")
@@ -2447,7 +2462,8 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
layout.separator()
layout.operator("mesh.bevel").vertex_only = True
layout.operator("mesh.convex_hull")
if with_bullet:
layout.operator("mesh.convex_hull")
layout.operator("mesh.vertices_smooth")
layout.operator("mesh.remove_doubles")
@@ -2681,8 +2697,7 @@ def draw_curve(self, context):
layout.separator()
layout.prop_menu_enum(toolsettings, "proportional_edit")
layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
layout.menu("VIEW3D_MT_edit_proportional")
layout.separator()
@@ -2841,8 +2856,7 @@ class VIEW3D_MT_edit_meta(Menu):
layout.separator()
layout.prop_menu_enum(toolsettings, "proportional_edit")
layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
layout.menu("VIEW3D_MT_edit_proportional")
layout.separator()
@@ -2879,8 +2893,7 @@ class VIEW3D_MT_edit_lattice(Menu):
layout.separator()
layout.prop_menu_enum(toolsettings, "proportional_edit")
layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
layout.menu("VIEW3D_MT_edit_proportional")
class VIEW3D_MT_edit_armature(Menu):
@@ -3040,8 +3053,7 @@ class VIEW3D_MT_edit_gpencil(Menu):
layout.separator()
layout.prop_menu_enum(toolsettings, "proportional_edit")
layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
layout.menu("VIEW3D_MT_edit_proportional")
layout.separator()

View File

@@ -59,7 +59,7 @@ AbcHairWriter::AbcHairWriter(Scene *scene,
{
m_psys = psys;
OCurves curves(parent->alembicXform(), m_name, m_time_sampling);
OCurves curves(parent->alembicXform(), psys->name, m_time_sampling);
m_schema = curves.getSchema();
}

View File

@@ -67,7 +67,7 @@ AbcPointsWriter::AbcPointsWriter(Scene *scene,
{
m_psys = psys;
OPoints points(parent->alembicXform(), m_name, m_time_sampling);
OPoints points(parent->alembicXform(), psys->name, m_time_sampling);
m_schema = points.getSchema();
}

View File

@@ -599,10 +599,6 @@ struct ImportJobData {
ABC_INLINE bool is_mesh_and_strands(const IObject &object)
{
if (object.getNumChildren() != 2) {
return false;
}
bool has_mesh = false;
bool has_curve = false;
@@ -624,6 +620,9 @@ ABC_INLINE bool is_mesh_and_strands(const IObject &object)
else if (ICurves::matches(md)) {
has_curve = true;
}
else if (IPoints::matches(md)) {
has_curve = true;
}
}
return has_mesh && has_curve;

View File

@@ -783,6 +783,7 @@ void DM_vertex_attributes_from_gpu(
struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs);
void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert, int loop);
void DM_draw_attrib_vertex_uniforms(const DMVertexAttribs *attribs);
void DM_calc_tangents_names_from_gpu(
const struct GPUVertexAttribs *gattribs,

View File

@@ -27,8 +27,8 @@
/* these lines are grep'd, watch out for our not-so-awesome regex
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 277
#define BLENDER_SUBVERSION 3
#define BLENDER_VERSION 278
#define BLENDER_SUBVERSION 0
/* Several breakages with 270, e.g. constraint deg vs rad */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 6

View File

@@ -80,6 +80,7 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
#include "GPU_shader.h"
#ifdef WITH_OPENSUBDIV
# include "BKE_depsgraph.h"
# include "DNA_userdef_types.h"
#endif
@@ -2282,7 +2283,7 @@ static void editbmesh_calc_modifiers(
{
ModifierData *md, *previewmd = NULL;
float (*deformedVerts)[3] = NULL;
CustomDataMask mask, previewmask = 0, append_mask = 0;
CustomDataMask mask = 0, previewmask = 0, append_mask = 0;
DerivedMesh *dm = NULL, *orcodm = NULL;
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
CDMaskLink *datamasks, *curr;
@@ -2566,7 +2567,7 @@ static void editbmesh_calc_modifiers(
* playback performance is kept as high as possible.
*/
static bool calc_modifiers_skip_orco(Scene *scene,
const Object *ob,
Object *ob,
bool use_render_params)
{
ModifierData *last_md = ob->modifiers.last;
@@ -2575,9 +2576,18 @@ static bool calc_modifiers_skip_orco(Scene *scene,
last_md->type == eModifierType_Subsurf &&
modifier_isEnabled(scene, last_md, required_mode))
{
if (U.opensubdiv_compute_type == USER_OPENSUBDIV_COMPUTE_NONE) {
return false;
}
else if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) {
return false;
}
else if ((DAG_get_eval_flags_for_object(scene, ob) & DAG_EVAL_NEED_CPU) != 0) {
return false;
}
SubsurfModifierData *smd = (SubsurfModifierData *)last_md;
/* TODO(sergey): Deduplicate this with checks from subsurf_ccg.c. */
return smd->use_opensubdiv && U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE;
return smd->use_opensubdiv != 0;
}
return false;
}
@@ -3797,7 +3807,6 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
glTexCoord3fv(orco);
else
glVertexAttrib3fv(attribs->orco.gl_index, orco);
glUniform1i(attribs->orco.gl_info_index, 0);
}
/* uv texture coordinates */
@@ -3816,7 +3825,6 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
glTexCoord2fv(uv);
else
glVertexAttrib2fv(attribs->tface[b].gl_index, uv);
glUniform1i(attribs->tface[b].gl_info_index, 0);
}
/* vertex colors */
@@ -3832,17 +3840,33 @@ void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert,
}
glVertexAttrib4fv(attribs->mcol[b].gl_index, col);
glUniform1i(attribs->mcol[b].gl_info_index, GPU_ATTR_INFO_SRGB);
}
/* tangent for normal mapping */
for (b = 0; b < attribs->tottang; b++) {
if (attribs->tang[b].array) {
/*const*/ float (*array)[4] = attribs->tang[b].array;
const float *tang = (array) ? array[a * 4 + vert] : zero;
const float *tang = (array) ? array[loop] : zero;
glVertexAttrib4fv(attribs->tang[b].gl_index, tang);
}
glUniform1i(attribs->tang[b].gl_info_index, 0);
}
}
void DM_draw_attrib_vertex_uniforms(const DMVertexAttribs *attribs)
{
int i;
if (attribs->totorco) {
glUniform1i(attribs->orco.gl_info_index, 0);
}
for (i = 0; i < attribs->tottface; i++) {
glUniform1i(attribs->tface[i].gl_info_index, 0);
}
for (i = 0; i < attribs->totmcol; i++) {
glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB);
}
for (i = 0; i < attribs->tottang; i++) {
glUniform1i(attribs->tang[i].gl_info_index, 0);
}
}

View File

@@ -941,8 +941,10 @@ static void cdDM_drawMappedFacesGLSL(
matnr = new_matnr;
do_draw = setMaterial(matnr + 1, &gattribs);
if (do_draw)
if (do_draw) {
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
DM_draw_attrib_vertex_uniforms(&attribs);
}
glBegin(GL_TRIANGLES);
}
@@ -1210,6 +1212,7 @@ static void cdDM_drawMappedFacesMat(
setMaterial(userData, matnr = new_matnr, &gattribs);
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
DM_draw_attrib_vertex_uniforms(&attribs);
glBegin(GL_TRIANGLES);
}

View File

@@ -1410,24 +1410,6 @@ static void emDM_drawMappedFacesTex(
emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
}
static void emdm_pass_attrib_update_uniforms(const DMVertexAttribs *attribs)
{
int i;
if (attribs->totorco) {
glUniform1i(attribs->orco.gl_info_index, 0);
}
for (i = 0; i < attribs->tottface; i++) {
glUniform1i(attribs->tface[i].gl_info_index, 0);
}
for (i = 0; i < attribs->totmcol; i++) {
glUniform1i(attribs->mcol[i].gl_info_index, GPU_ATTR_INFO_SRGB);
}
for (i = 0; i < attribs->tottang; i++) {
glUniform1i(attribs->tang[i].gl_info_index, 0);
}
}
/**
* \note
*
@@ -1548,7 +1530,7 @@ static void emDM_drawMappedFacesGLSL(
do_draw = setMaterial(matnr = new_matnr, &gattribs);
if (do_draw) {
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
emdm_pass_attrib_update_uniforms(&attribs);
DM_draw_attrib_vertex_uniforms(&attribs);
if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) {
BM_mesh_elem_index_ensure(bm, BM_LOOP);
}

View File

@@ -1138,7 +1138,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
/* increase user numbers */
id_us_plus((ID *)obn->data);
id_us_plus((ID *)obn->gpd);
id_lib_extern((ID *)obn->dup_group);
id_us_plus((ID *)obn->dup_group);
for (a = 0; a < obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);

View File

@@ -2820,12 +2820,13 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
int matnr = -1;
int do_draw = 0;
#define PASSATTRIB(dx, dy, vert) { \
if (attribs.totorco) \
index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
else \
index = 0; \
DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \
#define PASSATTRIB(dx, dy, vert) { \
if (attribs.totorco) \
index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
else \
index = 0; \
DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \
DM_draw_attrib_vertex_uniforms(&attribs); \
} (void)0
totpoly = ccgSubSurf_getNumFaces(ss);
@@ -3222,12 +3223,13 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
matnr = -1;
#define PASSATTRIB(dx, dy, vert) { \
if (attribs.totorco) \
index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
else \
index = 0; \
DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \
#define PASSATTRIB(dx, dy, vert) { \
if (attribs.totorco) \
index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
else \
index = 0; \
DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \
DM_draw_attrib_vertex_uniforms(&attribs); \
} (void)0
totface = ccgSubSurf_getNumFaces(ss);

View File

@@ -780,9 +780,10 @@ BLI_INLINE bool parallel_range_next_iter_get(
ParallelRangeState * __restrict state,
int * __restrict iter, int * __restrict count)
{
uint32_t previter = atomic_fetch_and_add_uint32((uint32_t *)(&state->iter), state->chunk_size);
uint32_t uval = atomic_fetch_and_add_uint32((uint32_t *)(&state->iter), state->chunk_size);
int previter = *(int32_t*)&uval;
*iter = (int)previter;
*iter = previter;
*count = max_ii(0, min_ii(state->chunk_size, state->stop - previter));
return (previter < state->stop);

View File

@@ -1348,7 +1348,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
/* ------- end of grease pencil initialization --------------- */
}
{
if (!MAIN_VERSION_ATLEAST(main, 278, 0)) {
if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingTrack", "float", "weight_stab")) {
MovieClip *clip;
for (clip = main->movieclip.first; clip; clip = clip->id.next) {

View File

@@ -1021,6 +1021,12 @@ void ED_keymap_ui(struct wmKeyConfig *keyconf);
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
int UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event);
/* UI_OT_space_context_cycle direction */
enum {
SPACE_CONTEXT_CYCLE_PREV,
SPACE_CONTEXT_CYCLE_NEXT,
};
bool UI_context_copy_to_selected_list(
struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
struct ListBase *r_lb, bool *r_use_path_from_id, char **r_path);

View File

@@ -1082,6 +1082,78 @@ static void UI_OT_drop_color(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
}
/* ------------------------------------------------------------------------- */
static EnumPropertyItem space_context_cycle_direction[] = {
{SPACE_CONTEXT_CYCLE_PREV, "PREV", 0, "Previous", ""},
{SPACE_CONTEXT_CYCLE_NEXT, "NEXT", 0, "Next", ""},
{0, NULL, 0, NULL, NULL}
};
static int space_context_cycle_poll(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
return ELEM(sa->spacetype, SPACE_BUTS, SPACE_USERPREF);
}
/**
* Helper to get the correct RNA pointer/property pair for changing
* the display context of active space type in \sa.
*/
static void context_cycle_prop_get(
bScreen *screen, const ScrArea *sa,
PointerRNA *r_ptr, PropertyRNA **r_prop)
{
const char *propname;
switch (sa->spacetype) {
case SPACE_BUTS:
RNA_pointer_create(&screen->id, &RNA_SpaceProperties, sa->spacedata.first, r_ptr);
propname = "context";
break;
case SPACE_USERPREF:
RNA_pointer_create(NULL, &RNA_UserPreferences, &U, r_ptr);
propname = "active_section";
break;
}
*r_prop = RNA_struct_find_property(r_ptr, propname);
}
static int space_context_cycle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
const int direction = RNA_enum_get(op->ptr, "direction");
PointerRNA ptr;
PropertyRNA *prop;
context_cycle_prop_get(CTX_wm_screen(C), CTX_wm_area(C), &ptr, &prop);
const int old_context = RNA_property_enum_get(&ptr, prop);
const int new_context = RNA_property_enum_step(
C, &ptr, prop, old_context,
direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1);
RNA_property_enum_set(&ptr, prop, new_context);
RNA_property_update(C, &ptr, prop);
return OPERATOR_FINISHED;
}
static void UI_OT_space_context_cycle(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Cycle Space Context";
ot->description = "Cycle through the editor context by activating the next/previous one";
ot->idname = "UI_OT_space_context_cycle";
/* api callbacks */
ot->invoke = space_context_cycle_invoke;
ot->poll = space_context_cycle_poll;
ot->flag = 0;
RNA_def_enum(ot->srna, "direction", space_context_cycle_direction, SPACE_CONTEXT_CYCLE_NEXT, "Direction",
"Direction to cycle through");
}
/* ********************************************************* */
@@ -1102,6 +1174,7 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_edittranslation_init);
#endif
WM_operatortype_append(UI_OT_reloadtranslation);
WM_operatortype_append(UI_OT_space_context_cycle);
/* external */
WM_operatortype_append(UI_OT_eyedropper_color);

View File

@@ -1841,6 +1841,52 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
#undef USE_FLAT_INACTIVE
}
static int ui_handle_panel_category_cycling(const wmEvent *event, ARegion *ar, const uiBut *active_but)
{
const bool is_mousewheel = ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
const bool inside_tabregion = (event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax);
/* if mouse is inside non-tab region, ctrl key is required */
if (is_mousewheel && !event->ctrl && !inside_tabregion)
return WM_UI_HANDLER_CONTINUE;
if (active_but && ui_but_supports_cycling(active_but)) {
/* skip - exception to make cycling buttons
* using ctrl+mousewheel work in tabbed regions */
}
else {
const char *category = UI_panel_category_active_get(ar, false);
if (LIKELY(category)) {
PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category);
if (LIKELY(pc_dyn)) {
if (is_mousewheel) {
/* we can probably get rid of this and only allow ctrl+tabbing */
pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
}
else {
const bool backwards = event->shift;
pc_dyn = backwards ? pc_dyn->prev : pc_dyn->next;
if (!pc_dyn) {
/* proper cyclic behavior, back to first/last category (only used for ctrl+tab) */
pc_dyn = backwards ? ar->panels_category.last : ar->panels_category.first;
}
}
if (pc_dyn) {
/* intentionally don't reset scroll in this case,
* this allows for quick browsing between tabs */
UI_panel_category_active_set(ar, pc_dyn->idname);
ED_region_tag_redraw(ar);
}
}
}
return WM_UI_HANDLER_BREAK;
}
return WM_UI_HANDLER_CONTINUE;
}
/* XXX should become modal keymap */
/* AKey is opening/closing panels, independent of button state now */
@@ -1853,6 +1899,7 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar, cons
retval = WM_UI_HANDLER_CONTINUE;
/* handle category tabs */
if (has_category_tabs) {
if (event->val == KM_PRESS) {
if (event->type == LEFTMOUSE) {
@@ -1867,32 +1914,9 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar, cons
retval = WM_UI_HANDLER_BREAK;
}
}
else if (ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
/* mouse wheel cycle tabs */
/* first check if the mouse is in the tab region */
if (event->ctrl || (event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax)) {
if (active_but && ui_but_supports_cycling(active_but)) {
/* skip - exception to make cycling buttons
* using ctrl+mousewheel work in tabbed regions */
}
else {
const char *category = UI_panel_category_active_get(ar, false);
if (LIKELY(category)) {
PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category);
if (LIKELY(pc_dyn)) {
pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
if (pc_dyn) {
/* intentionally don't reset scroll in this case,
* this allows for quick browsing between tabs */
UI_panel_category_active_set(ar, pc_dyn->idname);
ED_region_tag_redraw(ar);
}
}
}
retval = WM_UI_HANDLER_BREAK;
}
}
else if ((event->type == TABKEY && event->ctrl) || ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
/* cycle tabs */
retval = ui_handle_panel_category_cycling(event, ar, active_but);
}
}
}

View File

@@ -73,38 +73,6 @@
#define MENU_PADDING (int)(0.2f * UI_UNIT_Y)
#define MENU_BORDER (int)(0.3f * U.widget_unit)
static int rna_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int direction)
{
EnumPropertyItem *item_array;
int totitem;
bool free;
int value;
int i, i_init;
int step = (direction < 0) ? -1 : 1;
int step_tot = 0;
RNA_property_enum_items((bContext *)C, ptr, prop, &item_array, &totitem, &free);
value = RNA_property_enum_get(ptr, prop);
i = RNA_enum_from_value(item_array, value);
i_init = i;
do {
i = mod_i(i + step, totitem);
if (item_array[i].identifier[0]) {
step_tot += step;
}
} while ((i != i_init) && (step_tot != direction));
if (i != i_init) {
value = item_array[i].value;
}
if (free) {
MEM_freeN(item_array);
}
return value;
}
bool ui_but_menu_step_poll(const uiBut *but)
{
@@ -122,7 +90,8 @@ int ui_but_menu_step(uiBut *but, int direction)
return but->menu_step_func(but->block->evil_C, direction, but->poin);
}
else {
return rna_property_enum_step(but->block->evil_C, &but->rnapoin, but->rnaprop, direction);
const int curval = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
return RNA_property_enum_step(but->block->evil_C, &but->rnapoin, but->rnaprop, curval, direction);
}
}

View File

@@ -3121,8 +3121,10 @@ static void mesh_separate_material_assign_mat_nr(Main *bmain, Object *ob, const
BKE_material_resize_id(bmain, obdata, 1, true);
ob->mat[0] = ma_ob;
id_us_plus((ID *)ma_ob);
ob->matbits[0] = matbit;
(*matarar)[0] = ma_obdata;
id_us_plus((ID *)ma_obdata);
}
else {
BKE_material_clear_id(bmain, obdata, true);

View File

@@ -998,7 +998,7 @@ static int group_instance_add_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_add_type(C, OB_EMPTY, group->id.name + 2, loc, rot, false, layer);
ob->dup_group = group;
ob->transflag |= OB_DUPLIGROUP;
id_lib_extern(&group->id);
id_us_plus(&group->id);
/* works without this except if you try render right after, see: 22027 */
DAG_relations_tag_update(bmain);

View File

@@ -910,7 +910,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
base->object->dup_group = ob->dup_group;
if (ob->dup_group)
id_lib_extern(&ob->dup_group->id);
id_us_plus(&ob->dup_group->id);
}
else if (event == 7) { /* mass */
base->object->mass = ob->mass;

View File

@@ -1609,7 +1609,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
case MAKE_LINKS_DUPLIGROUP:
ob_dst->dup_group = ob_src->dup_group;
if (ob_dst->dup_group) {
id_lib_extern(&ob_dst->dup_group->id);
id_us_plus(&ob_dst->dup_group->id);
ob_dst->transflag |= OB_DUPLIGROUP;
}
break;

View File

@@ -4331,7 +4331,13 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_screencast", F3KEY, KM_PRESS, KM_ALT, 0);
/* UI */
kmi = WM_keymap_add_item(keymap, "UI_OT_space_context_cycle", TABKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_NEXT);
kmi = WM_keymap_add_item(keymap, "UI_OT_space_context_cycle", TABKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", SPACE_CONTEXT_CYCLE_PREV);
/* tests */
WM_keymap_add_item(keymap, "SCREEN_OT_region_quadview", QKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0);

View File

@@ -217,32 +217,56 @@ static void SOUND_OT_open_mono(wmOperatorType *ot)
/* ******************************************************* */
static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op))
static void sound_update_animation_flags(Scene *scene);
static int sound_update_animation_flags_cb(Sequence *seq, void *user_data)
{
struct FCurve *fcu;
Scene *scene = (Scene *)user_data;
bool driven;
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven);
if (fcu || driven)
seq->flag |= SEQ_AUDIO_VOLUME_ANIMATED;
else
seq->flag &= ~SEQ_AUDIO_VOLUME_ANIMATED;
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven);
if (fcu || driven)
seq->flag |= SEQ_AUDIO_PITCH_ANIMATED;
else
seq->flag &= ~SEQ_AUDIO_PITCH_ANIMATED;
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven);
if (fcu || driven)
seq->flag |= SEQ_AUDIO_PAN_ANIMATED;
else
seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED;
if (seq->type == SEQ_TYPE_SCENE) {
/* TODO(sergey): For now we do manual recursion into the scene strips,
* but perhaps it should be covered by recursive_apply?
*/
sound_update_animation_flags(seq->scene);
}
return 0;
}
static void sound_update_animation_flags(Scene *scene)
{
Sequence *seq;
Scene *scene = CTX_data_scene(C);
struct FCurve *fcu;
bool driven;
Sequence *seq;
if (scene->id.tag & LIB_TAG_DOIT) {
return;
}
scene->id.tag |= LIB_TAG_DOIT;
SEQ_BEGIN(scene->ed, seq)
{
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, &driven);
if (fcu || driven)
seq->flag |= SEQ_AUDIO_VOLUME_ANIMATED;
else
seq->flag &= ~SEQ_AUDIO_VOLUME_ANIMATED;
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pitch", 0, &driven);
if (fcu || driven)
seq->flag |= SEQ_AUDIO_PITCH_ANIMATED;
else
seq->flag &= ~SEQ_AUDIO_PITCH_ANIMATED;
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "pan", 0, &driven);
if (fcu || driven)
seq->flag |= SEQ_AUDIO_PAN_ANIMATED;
else
seq->flag &= ~SEQ_AUDIO_PAN_ANIMATED;
BKE_sequencer_recursive_apply(seq, sound_update_animation_flags_cb, scene);
}
SEQ_END
@@ -251,7 +275,12 @@ static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op)
scene->audio.flag |= AUDIO_VOLUME_ANIMATED;
else
scene->audio.flag &= ~AUDIO_VOLUME_ANIMATED;
}
static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op))
{
BKE_main_id_tag_idcode(CTX_data_main(C), ID_SCE, LIB_TAG_DOIT, false);
sound_update_animation_flags(CTX_data_scene(C));
return OPERATOR_FINISHED;
}

View File

@@ -1608,6 +1608,11 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
/* imtype */
simopts->im_format = scene->r.im_format;
is_depth_set = true;
if (!BKE_image_is_multiview(ima)) {
/* In case multiview is disabled, render settings would be invalid for render result in this area. */
simopts->im_format.stereo3d_format = *ima->stereo3d_format;
simopts->im_format.views_format = ima->views_format;
}
}
else {
if (ima->source == IMA_SRC_GENERATED) {

View File

@@ -4227,7 +4227,7 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
/* If we are drawing shadows and any of the materials don't cast a shadow,
* then don't draw the object */
if (v3d->flag2 & V3D_RENDER_SHADOW) {
for (int i = 0; i < ob->totcol; ++i) {
for (int i = 1; i <= ob->totcol; ++i) {
Material *ma = give_current_material(ob, i);
if (ma && !(ma->mode2 & MA_CASTSHADOW)) {
return true;

View File

@@ -916,6 +916,7 @@ int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value);
int RNA_property_enum_get_default(PointerRNA *ptr, PropertyRNA *prop);
void *RNA_property_enum_py_data_get(PropertyRNA *prop);
int RNA_property_enum_step(const struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int from_value, int direction);
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value);

View File

@@ -2873,6 +2873,45 @@ void *RNA_property_enum_py_data_get(PropertyRNA *prop)
return eprop->py_data;
}
/**
* Get the value of the item that is \a step items away from \a from_value.
*
* \param from_value: Item value to start stepping from.
* \param step: Absolute value defines step size, sign defines direction.
* E.g to get the next item, pass 1, for the previous -1.
*/
int RNA_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int from_value, int step)
{
EnumPropertyItem *item_array;
int totitem;
bool free;
int result_value = from_value;
int i, i_init;
int single_step = (step < 0) ? -1 : 1;
int step_tot = 0;
RNA_property_enum_items((bContext *)C, ptr, prop, &item_array, &totitem, &free);
i = RNA_enum_from_value(item_array, from_value);
i_init = i;
do {
i = mod_i(i + single_step, totitem);
if (item_array[i].identifier[0]) {
step_tot += single_step;
}
} while ((i != i_init) && (step_tot != step));
if (i != i_init) {
result_value = item_array[i].value;
}
if (free) {
MEM_freeN(item_array);
}
return result_value;
}
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
{
PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;

View File

@@ -618,7 +618,7 @@ void RNA_api_ui_layout(StructRNA *srna)
#endif
func = RNA_def_function(srna, "label", "rna_uiItemL");
RNA_def_function_ui_description(func, "Item. Display text and/or icon in the layout");
RNA_def_function_ui_description(func, "Item. Displays text and/or icon in the layout");
api_ui_item_common(func);
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
@@ -644,6 +644,7 @@ void RNA_api_ui_layout(StructRNA *srna)
/* templates */
func = RNA_def_function(srna, "template_header", "uiTemplateHeader");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Inserts common Space header UI (editor type selector)");
func = RNA_def_function(srna, "template_ID", "uiTemplateID");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@@ -853,9 +854,12 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_header_3D", "uiTemplateHeader3D");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Inserts common 3DView header UI (selectors for context mode, shading, etc.)");
func = RNA_def_function(srna, "template_edit_mode_selection", "uiTemplateEditModeSelection");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Inserts common 3DView Edit modes header UI (selector for selection mode)");
func = RNA_def_function(srna, "template_reports_banner", "uiTemplateReportsBanner");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);

View File

@@ -398,18 +398,21 @@ void RNA_api_wm(StructRNA *srna)
rna_generic_op_invoke(func, 0);
func = RNA_def_function(srna, "modal_handler_add", "rna_event_modal_handler_add");
RNA_def_function_ui_description(func, "Add a modal handler to the window manager, for the given modal operator "
"(called by invoke() with self, just before returning {'RUNNING_MODAL'})");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "operator", "Operator", "", "Operator to call");
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_function_return(func, RNA_def_boolean(func, "handle", 1, "", ""));
RNA_def_function_return(func, RNA_def_boolean(func, "handle", 1, "", "Whether adding the handler was successful"));
func = RNA_def_function(srna, "event_timer_add", "rna_event_timer_add");
RNA_def_function_ui_description(func, "Add a timer to the given window, to generate periodic 'TIMER' events");
parm = RNA_def_property(func, "time_step", PROP_FLOAT, PROP_NONE);
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_property_range(parm, 0.0, FLT_MAX);
RNA_def_property_ui_text(parm, "Time Step", "Interval in seconds between timer events");
RNA_def_pointer(func, "window", "Window", "", "Window to attach the timer to or None");
RNA_def_pointer(func, "window", "Window", "", "Window to attach the timer to, or None");
parm = RNA_def_pointer(func, "result", "Timer", "", "");
RNA_def_function_return(func, parm);
@@ -421,44 +424,49 @@ void RNA_api_wm(StructRNA *srna)
/* Progress bar interface */
func = RNA_def_function(srna, "progress_begin", "rna_progress_begin");
RNA_def_function_ui_description(func, "Start progress report");
parm = RNA_def_property(func, "min", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(parm, "min", "any value in range [0,9999]");
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_property(func, "max", PROP_FLOAT, PROP_NONE);
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_property_ui_text(parm, "max", "any value in range [min+1,9998]");
func = RNA_def_function(srna, "progress_update", "rna_progress_update");
RNA_def_function_ui_description(func, "Update the progress feedback");
parm = RNA_def_property(func, "value", PROP_FLOAT, PROP_NONE);
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_property_ui_text(parm, "value", "any value between min and max as set in progress_begin()");
RNA_def_property_ui_text(parm, "value", "Any value between min and max as set in progress_begin()");
func = RNA_def_function(srna, "progress_end", "rna_progress_end");
RNA_def_function_ui_description(func, "Terminate progress report");
/* invoke functions, for use with python */
func = RNA_def_function(srna, "invoke_props_popup", "rna_Operator_props_popup");
RNA_def_function_ui_description(func, "Operator popup invoke");
RNA_def_function_ui_description(func, "Operator popup invoke "
"(show operator properties and execute it automatically on changes)");
rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN);
/* invoked dialog opens popup with OK button, does not auto-exec operator. */
func = RNA_def_function(srna, "invoke_props_dialog", "WM_operator_props_dialog_popup");
RNA_def_function_ui_description(func, "Operator dialog (non-autoexec popup) invoke");
RNA_def_function_ui_description(func, "Operator dialog (non-autoexec popup) invoke "
"(show operator properties and only execute it on click on OK button)");
rna_generic_op_invoke(func, WM_GEN_INVOKE_SIZE | WM_GEN_INVOKE_RETURN);
/* invoke enum */
func = RNA_def_function(srna, "invoke_search_popup", "rna_Operator_enum_search_invoke");
RNA_def_function_ui_description(func, "Operator search popup invoke (search in values of "
"operator's type 'prop' EnumProperty, and execute it on confirmation)");
rna_generic_op_invoke(func, 0);
/* invoke functions, for use with python */
func = RNA_def_function(srna, "invoke_popup", "WM_operator_ui_popup");
RNA_def_function_ui_description(func, "Operator popup invoke");
RNA_def_function_ui_description(func, "Operator popup invoke "
"(only shows operator's properties, without executing it)");
rna_generic_op_invoke(func, WM_GEN_INVOKE_SIZE | WM_GEN_INVOKE_RETURN);
func = RNA_def_function(srna, "invoke_confirm", "rna_Operator_confirm");
RNA_def_function_ui_description(func, "Operator confirmation");
RNA_def_function_ui_description(func, "Operator confirmation popup "
"(only to let user confirm the execution, no operator properties shown)");
rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN);

View File

@@ -130,6 +130,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (U.opensubdiv_compute_type == USER_OPENSUBDIV_COMPUTE_NONE) {
modifier_setError(md, "OpenSubdiv is disabled in User Preferences");
}
else if ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) != 0) {
modifier_setError(md, "OpenSubdiv is not supported in paint modes");
}
else if ((DAG_get_eval_flags_for_object(md->scene, ob) & DAG_EVAL_NEED_CPU) == 0) {
subsurf_flags |= SUBSURF_USE_GPU_BACKEND;
do_cddm_convert = false;

View File

@@ -338,7 +338,8 @@ if(WITH_PYTHON)
# install(CODE "message(\"copying blender scripts...\")")
# exclude addons_contrib if release
if("${BLENDER_VERSION_CYCLE}" STREQUAL "release")
if("${BLENDER_VERSION_CYCLE}" STREQUAL "release" OR
"${BLENDER_VERSION_CYCLE}" STREQUAL "rc")
set(ADDON_EXCLUDE_CONDITIONAL "addons_contrib/*")
else()
set(ADDON_EXCLUDE_CONDITIONAL "_addons_contrib/*") # dummy, wont do anything