diff options
31 files changed, 528 insertions, 153 deletions
diff --git a/doc/python_api/sphinx_changelog_gen.py b/doc/python_api/sphinx_changelog_gen.py index 4cbb418e326..8758590dbae 100644 --- a/doc/python_api/sphinx_changelog_gen.py +++ b/doc/python_api/sphinx_changelog_gen.py @@ -27,7 +27,7 @@ output from this tool should be added into "doc/python_api/rst/change_log.rst" blender --background --python doc/python_api/sphinx_changelog_gen.py -- --dump # create changelog -blender --background --python doc/python_api/sphinx_changelog_gen.py -- \ +blender --background --factory-startup --python doc/python_api/sphinx_changelog_gen.py -- \ --api_from blender_2_63_0.py \ --api_to blender_2_64_0.py \ --api_out changes.rst @@ -331,7 +331,7 @@ def main(): # When --help or no args are given, print this help usage_text = "Run blender in background mode with this script: " - "blender --background --python %s -- [options]" % os.path.basename(__file__) + "blender --background --factory-startup --python %s -- [options]" % os.path.basename(__file__) epilog = "Run this before releases" diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 4a109a44ec0..2fbbd16a461 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -26,16 +26,16 @@ API dump in RST files --------------------- Run this script from Blender's root path once you have compiled Blender - ./blender.bin --background -noaudio --python doc/python_api/sphinx_doc_gen.py + blender --background --factory-startup -noaudio --python doc/python_api/sphinx_doc_gen.py This will generate python files in doc/python_api/sphinx-in/ - providing ./blender.bin is or links to the blender executable + providing ./blender is or links to the blender executable To choose sphinx-in directory: - ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api + blender --background --factory-startup --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api For quick builds: - ./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial bmesh.* + blender --background --factory-startup --python doc/python_api/sphinx_doc_gen.py -- --partial bmesh.* Sphinx: HTML generation @@ -46,8 +46,6 @@ Sphinx: HTML generation cd doc/python_api sphinx-build sphinx-in sphinx-out - This requires sphinx 1.0.7 to be installed. - Sphinx: PDF generation ---------------------- @@ -68,7 +66,7 @@ except ImportError: import sys sys.exit() -import rna_info # Blender module +import rna_info # Blender module def rna_info_BuildRNAInfo_cache(): @@ -86,7 +84,7 @@ import shutil import logging from platform import platform -PLATFORM = platform().split('-')[0].lower() # 'linux', 'darwin', 'windows' +PLATFORM = platform().split('-')[0].lower() # 'linux', 'darwin', 'windows' SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) @@ -208,12 +206,12 @@ BPY_LOGGER.setLevel(logging.DEBUG) """ # for quick rebuilds rm -rf /b/doc/python_api/sphinx-* && \ -./blender.bin -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py && \ +./blender -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py && \ sphinx-build doc/python_api/sphinx-in doc/python_api/sphinx-out or -./blender.bin -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B +./blender -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B """ # Switch for quick testing so doc-builds don't take so long @@ -420,7 +418,7 @@ MODULE_GROUPING = { blender_version_strings = [str(v) for v in bpy.app.version] -# converting bytes to strings, due to #30154 +# converting bytes to strings, due to T30154 BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8') BLENDER_DATE = str(bpy.app.build_date, 'utf_8') @@ -1567,9 +1565,9 @@ def pyrna2sphinx(basepath): # operators def write_ops(): - API_BASEURL = "http://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts" - API_BASEURL_ADDON = "http://svn.blender.org/svnroot/bf-extensions/trunk/py/scripts" - API_BASEURL_ADDON_CONTRIB = "http://svn.blender.org/svnroot/bf-extensions/contrib/py/scripts" + API_BASEURL = "https://developer.blender.org/diffusion/B/browse/master/release/scripts/ " + API_BASEURL_ADDON = "https://developer.blender.org/diffusion/BA/" + API_BASEURL_ADDON_CONTRIB = "https://developer.blender.org/diffusion/BAC/" op_modules = {} for op in ops.values(): @@ -1645,7 +1643,7 @@ def write_sphinx_conf_py(basepath): if ARGS.sphinx_theme == "blender-org": fw("html_theme_path = ['../']\n") - # copied with the theme, exclude else we get an error [#28873] + # copied with the theme, exclude else we get an error [T28873] fw("html_favicon = 'favicon.ico'\n") # in <theme>/static/ # not helpful since the source is generated, adds to upload size. diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index dd5328220ab..b505bd54e5e 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -107,6 +107,67 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, /* Calculate vertices relative to ray origin. */ const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, triAddr); + +#if defined(__KERNEL_AVX2__) + const avxf avxf_P(P.m128, P.m128); + + const avxf tri_ab = kernel_tex_fetch_avxf(__prim_tri_verts, tri_vindex + 0); + const avxf tri_bc = kernel_tex_fetch_avxf(__prim_tri_verts, tri_vindex + 1); + + const avxf AB = tri_ab - avxf_P; + const avxf BC = tri_bc - avxf_P; + + const __m256i permuteMask = _mm256_set_epi32(0x3, kz, ky, kx, 0x3, kz, ky, kx); + + const avxf AB_k = shuffle(AB, permuteMask); + const avxf BC_k = shuffle(BC, permuteMask); + + /* Akz, Akz, Bkz, Bkz, Bkz, Bkz, Ckz, Ckz */ + const avxf ABBC_kz = shuffle<2>(AB_k, BC_k); + + /* Akx, Aky, Bkx, Bky, Bkx,Bky, Ckx, Cky */ + const avxf ABBC_kxy = shuffle<0,1,0,1>(AB_k, BC_k); + + const avxf Sxy(Sy, Sx, Sy, Sx); + + /* Ax, Ay, Bx, By, Bx, By, Cx, Cy */ + const avxf ABBC_xy = nmadd(ABBC_kz, Sxy, ABBC_kxy); + + float ABBC_kz_array[8]; + _mm256_storeu_ps((float*)&ABBC_kz_array, ABBC_kz); + + const float A_kz = ABBC_kz_array[0]; + const float B_kz = ABBC_kz_array[2]; + const float C_kz = ABBC_kz_array[6]; + + /* By, Bx, Cy, Cx, By, Bx, Ay, Ax */ + const avxf BCBA_yx = permute<3,2,7,6,3,2,1,0>(ABBC_xy); + + const avxf negMask(0,0,0,0,0x80000000, 0x80000000, 0x80000000, 0x80000000); + + /* W U V + * (AxBy-AyBx) (BxCy-ByCx) XX XX (BxBy-ByBx) (CxAy-CyAx) XX XX + */ + const avxf WUxxxxVxx_neg = _mm256_hsub_ps(ABBC_xy * BCBA_yx, negMask /* Dont care */); + + const avxf WUVWnegWUVW = permute<0,1,5,0,0,1,5,0>(WUxxxxVxx_neg) ^ negMask; + + /* Calculate scaled barycentric coordinates. */ + float WUVW_array[4]; + _mm_storeu_ps((float*)&WUVW_array, _mm256_castps256_ps128 (WUVWnegWUVW)); + + const float W = WUVW_array[0]; + const float U = WUVW_array[1]; + const float V = WUVW_array[2]; + + const int WUVW_mask = 0x7 & _mm256_movemask_ps(WUVWnegWUVW); + const int WUVW_zero = 0x7 & _mm256_movemask_ps(_mm256_cmp_ps(WUVWnegWUVW, + _mm256_setzero_ps(), 0)); + + if(!((WUVW_mask == 7) || (WUVW_mask == 0)) && ((WUVW_mask | WUVW_zero) != 7)) { + return false; + } +#else const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0), tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1), tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2); @@ -135,6 +196,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, { return false; } +#endif /* Calculate determinant. */ float det = U + V + W; diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h index 7b30df04550..9d1f3bdc918 100644 --- a/intern/cycles/kernel/kernel_compat_cpu.h +++ b/intern/cycles/kernel/kernel_compat_cpu.h @@ -71,6 +71,20 @@ template<typename T> struct texture { return data[index]; } +#ifdef __KERNEL_AVX__ + /* Reads 256 bytes but indexes in blocks of 128 bytes to maintain + * compatibility with existing indicies and data structures. + */ + ccl_always_inline avxf fetch_avxf(const int index) + { + kernel_assert(index >= 0 && (index+1) < width); + ssef *ssefData = (ssef*)data; + ssef *ssefNodeData = &ssefData[index]; + return _mm256_loadu_ps((float *)ssefNodeData); + } + +#endif + #ifdef __KERNEL_SSE2__ ccl_always_inline ssef fetch_ssef(int index) { @@ -506,6 +520,7 @@ typedef texture_image<half4> texture_image_half4; /* Macros to handle different memory storage on different devices */ #define kernel_tex_fetch(tex, index) (kg->tex.fetch(index)) +#define kernel_tex_fetch_avxf(tex, index) (kg->tex.fetch_avxf(index)) #define kernel_tex_fetch_ssef(tex, index) (kg->tex.fetch_ssef(index)) #define kernel_tex_fetch_ssei(tex, index) (kg->tex.fetch_ssei(index)) #define kernel_tex_lookup(tex, t, offset, size) (kg->tex.lookup(t, offset, size)) diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h index f03fe288a0c..52c05b85aee 100644 --- a/intern/cycles/kernel/kernel_subsurface.h +++ b/intern/cycles/kernel/kernel_subsurface.h @@ -85,16 +85,11 @@ ccl_device ShaderClosure *subsurface_scatter_pick_closure(KernelGlobals *kg, Sha return NULL; } -#ifndef __KERNEL_GPU__ -ccl_device_noinline -#else -ccl_device_inline -#endif -float3 subsurface_scatter_eval(ShaderData *sd, - ShaderClosure *sc, - float disk_r, - float r, - bool all) +ccl_device_inline float3 subsurface_scatter_eval(ShaderData *sd, + ShaderClosure *sc, + float disk_r, + float r, + bool all) { #ifdef BSSRDF_MULTI_EVAL /* this is the veach one-sample model with balance heuristic, some pdf @@ -223,14 +218,9 @@ ccl_device void subsurface_color_bump_blur(KernelGlobals *kg, /* Subsurface scattering step, from a point on the surface to other * nearby points on the same object. */ -#ifndef __KERNEL_CUDA__ -ccl_device -#else -ccl_device_inline -#endif -int subsurface_scatter_multi_intersect( +ccl_device_inline int subsurface_scatter_multi_intersect( KernelGlobals *kg, - SubsurfaceIntersection* ss_isect, + SubsurfaceIntersection *ss_isect, ShaderData *sd, ShaderClosure *sc, uint *lcg_state, @@ -330,6 +320,10 @@ int subsurface_scatter_multi_intersect( verts); } #endif /* __OBJECT_MOTION__ */ + else { + ss_isect->weight[hit] = make_float3(0.0f, 0.0f, 0.0f); + continue; + } float3 hit_Ng = ss_isect->Ng[hit]; if(ss_isect->hits[hit].object != OBJECT_NONE) { diff --git a/intern/cycles/kernel/kernels/cpu/kernel.cpp b/intern/cycles/kernel/kernels/cpu/kernel.cpp index f11c85d5f6a..1559b0d7322 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel.cpp +++ b/intern/cycles/kernel/kernels/cpu/kernel.cpp @@ -45,6 +45,7 @@ # define __KERNEL_AVX__ # endif # ifdef __AVX2__ +# define __KERNEL_SSE__ # define __KERNEL_AVX2__ # endif #endif diff --git a/intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp b/intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp index 7351e2bad6b..1a416e771ee 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp +++ b/intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp @@ -20,6 +20,7 @@ /* SSE optimization disabled for now on 32 bit, see bug #36316 */ #if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86))) +# define __KERNEL_SSE__ # define __KERNEL_SSE2__ # define __KERNEL_SSE3__ # define __KERNEL_SSSE3__ diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index ed8c7056aaa..131ec824be3 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -321,8 +321,8 @@ void ShaderGraph::finalize(Scene *scene, * modified afterwards. */ if(!finalized) { - clean(scene); default_inputs(do_osl); + clean(scene); refine_bump_nodes(); if(do_bump) diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index f5674bdc15c..02ee4cd6774 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -63,6 +63,7 @@ set(SRC_HEADERS util_sky_model.cpp util_sky_model.h util_sky_model_data.h + util_avxf.h util_sseb.h util_ssef.h util_ssei.h diff --git a/intern/cycles/util/util_avxf.h b/intern/cycles/util/util_avxf.h new file mode 100644 index 00000000000..2db2c4dad1a --- /dev/null +++ b/intern/cycles/util/util_avxf.h @@ -0,0 +1,185 @@ +/* + * Copyright 2016 Intel Corporation + * + * 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. + */ + +#ifndef __UTIL_AVXF_H__ +#define __UTIL_AVXF_H__ + +CCL_NAMESPACE_BEGIN + +#ifdef __KERNEL_AVX__ +struct avxf +{ + typedef avxf Float; + + enum { size = 8 }; /* Number of SIMD elements. */ + + union { + __m256 m256; + float f[8]; + int i[8]; + }; + + __forceinline avxf () {} + __forceinline avxf (const avxf& other) { m256 = other.m256; } + __forceinline avxf& operator=(const avxf& other) { m256 = other.m256; return *this; } + + __forceinline avxf(const __m256 a) : m256(a) {} + __forceinline avxf(const __m256i a) : m256(_mm256_castsi256_ps (a)) {} + + __forceinline operator const __m256&(void) const { return m256; } + __forceinline operator __m256&(void) { return m256; } + + __forceinline avxf (float a) : m256(_mm256_set1_ps(a)) {} + + __forceinline avxf(float high32x4, float low32x4) : + m256(_mm256_set_ps(high32x4, high32x4, high32x4, high32x4, low32x4, low32x4, low32x4, low32x4)) {} + + __forceinline avxf(float a3, float a2, float a1, float a0) : + m256(_mm256_set_ps(a3, a2, a1, a0, a3, a2, a1, a0)) {} + + __forceinline avxf(float a7, float a6, float a5, float a4, float a3, float a2, float a1, float a0) : + m256(_mm256_set_ps(a7, a6, a5, a4, a3, a2, a1, a0)) {} + + + __forceinline avxf(int a3, int a2, int a1, int a0) + { + const __m256i foo = _mm256_set_epi32(a3, a2, a1, a0, a3, a2, a1, a0); + m256 = _mm256_castsi256_ps(foo); + } + + + __forceinline avxf(int a7, int a6, int a5, int a4, int a3, int a2, int a1, int a0) + { + const __m256i foo = _mm256_set_epi32(a7, a6, a5, a4, a3, a2, a1, a0); + m256 = _mm256_castsi256_ps(foo); + } + + __forceinline avxf(__m128 a, __m128 b) + { + const __m256 foo = _mm256_castps128_ps256(a); + m256 = _mm256_insertf128_ps(foo, b, 1); + } + +}; + +//////////////////////////////////////////////////////////////////////////////// +/// Unary Operators +//////////////////////////////////////////////////////////////////////////////// + +__forceinline const avxf mm256_sqrt(const avxf& a) { return _mm256_sqrt_ps(a.m256); } + +//////////////////////////////////////////////////////////////////////////////// +/// Binary Operators +//////////////////////////////////////////////////////////////////////////////// + +__forceinline const avxf operator +(const avxf& a, const avxf& b) { return _mm256_add_ps(a.m256, b.m256); } +__forceinline const avxf operator +(const avxf& a, const float& b) { return a + avxf(b); } +__forceinline const avxf operator +(const float& a, const avxf& b) { return avxf(a) + b; } + +__forceinline const avxf operator -(const avxf& a, const avxf& b) { return _mm256_sub_ps(a.m256, b.m256); } +__forceinline const avxf operator -(const avxf& a, const float& b) { return a - avxf(b); } +__forceinline const avxf operator -(const float& a, const avxf& b) { return avxf(a) - b; } + +__forceinline const avxf operator *(const avxf& a, const avxf& b) { return _mm256_mul_ps(a.m256, b.m256); } +__forceinline const avxf operator *(const avxf& a, const float& b) { return a * avxf(b); } +__forceinline const avxf operator *(const float& a, const avxf& b) { return avxf(a) * b; } + +__forceinline const avxf operator /(const avxf& a, const avxf& b) { return _mm256_div_ps(a.m256,b.m256); } +__forceinline const avxf operator /(const avxf& a, const float& b) { return a/avxf(b); } +__forceinline const avxf operator /(const float& a, const avxf& b) { return avxf(a)/b; } + +__forceinline const avxf operator|(const avxf& a, const avxf& b) { return _mm256_or_ps(a.m256,b.m256); } + +__forceinline const avxf operator^(const avxf& a, const avxf& b) { return _mm256_xor_ps(a.m256,b.m256); } + +__forceinline const avxf operator&(const avxf& a, const avxf& b) { return _mm256_and_ps(a.m256,b.m256); } + +//////////////////////////////////////////////////////////////////////////////// +/// Movement/Shifting/Shuffling Functions +//////////////////////////////////////////////////////////////////////////////// + +__forceinline const avxf shuffle(const avxf& a, const __m256i &shuf) { + return _mm256_permutevar_ps(a, shuf); +} + +template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7> __forceinline const avxf shuffle(const avxf& a) { + return _mm256_permutevar_ps(a, _mm256_set_epi32( i7,i6,i5,i4 ,i3,i2,i1,i0)); +} + +template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const avxf shuffle(const avxf& a, const avxf& b) { + return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); +} +template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const avxf shuffle(const avxf& a) { + return shuffle<i0,i1,i2,i3>(a,a); +} +template<size_t i0> __forceinline const avxf shuffle(const avxf& a, const avxf& b) { + return shuffle<i0,i0,i0,i0>(a, b); +} +template<size_t i0> __forceinline const avxf shuffle(const avxf& a) { + return shuffle<i0>(a,a); +} + +template<int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7> __forceinline const avxf permute(const avxf& a) { +#ifdef __KERNEL_AVX2__ + return _mm256_permutevar8x32_ps(a,_mm256_set_epi32( i7,i6,i5,i4 ,i3,i2,i1,i0)); +#else + float temp[8]; + _mm256_storeu_ps((float*)&temp, a); + return avxf(temp[i7], temp[i6], temp[i5], temp[i4], temp[i3], temp[i2], temp[i1], temp[i0]); +#endif +} + +template<int S0, int S1, int S2, int S3,int S4,int S5,int S6, int S7> +ccl_device_inline const avxf set_sign_bit(const avxf &a) +{ + return a ^ avxf(S7 << 31, S6 << 31, S5 << 31, S4 << 31, S3 << 31,S2 << 31,S1 << 31,S0 << 31); +} + +template<size_t S0, size_t S1, size_t S2, size_t S3,size_t S4,size_t S5,size_t S6, size_t S7> +ccl_device_inline const avxf blend(const avxf &a, const avxf &b) +{ + return _mm256_blend_ps(a,b,S7 << 0 | S6 << 1 | S5 << 2 | S4 << 3 | S3 << 4 | S2 << 5 | S1 << 6 | S0 << 7); +} + +template<size_t S0, size_t S1, size_t S2, size_t S3 > +ccl_device_inline const avxf blend(const avxf &a, const avxf &b) +{ + return blend<S0,S1,S2,S3,S0,S1,S2,S3>(a,b); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Ternary Operators +//////////////////////////////////////////////////////////////////////////////// +__forceinline const avxf madd (const avxf& a, const avxf& b, const avxf& c) { +#ifdef __KERNEL_AVX2__ + return _mm256_fmadd_ps(a,b,c); +#else + return c+(a*b); +#endif +} + +__forceinline const avxf nmadd(const avxf& a, const avxf& b, const avxf& c) { +#ifdef __KERNEL_AVX2__ + return _mm256_fnmadd_ps(a, b, c); +#else + return c-(a*b); +#endif +} +#endif + +CCL_NAMESPACE_END + +#endif diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 89a882d9b9d..ce2e4e5c30d 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -233,7 +233,7 @@ ccl_device_inline int mod(int x, int m) #ifndef __KERNEL_OPENCL__ -ccl_device_inline bool is_zero(const float2 a) +ccl_device_inline bool is_zero(const float2& a) { return (a.x == 0.0f && a.y == 0.0f); } @@ -242,7 +242,7 @@ ccl_device_inline bool is_zero(const float2 a) #ifndef __KERNEL_OPENCL__ -ccl_device_inline float average(const float2 a) +ccl_device_inline float average(const float2& a) { return (a.x + a.y)*(1.0f/2.0f); } @@ -251,58 +251,58 @@ ccl_device_inline float average(const float2 a) #ifndef __KERNEL_OPENCL__ -ccl_device_inline float2 operator-(const float2 a) +ccl_device_inline float2 operator-(const float2& a) { return make_float2(-a.x, -a.y); } -ccl_device_inline float2 operator*(const float2 a, const float2 b) +ccl_device_inline float2 operator*(const float2& a, const float2& b) { return make_float2(a.x*b.x, a.y*b.y); } -ccl_device_inline float2 operator*(const float2 a, float f) +ccl_device_inline float2 operator*(const float2& a, float f) { return make_float2(a.x*f, a.y*f); } -ccl_device_inline float2 operator*(float f, const float2 a) +ccl_device_inline float2 operator*(float f, const float2& a) { return make_float2(a.x*f, a.y*f); } -ccl_device_inline float2 operator/(float f, const float2 a) +ccl_device_inline float2 operator/(float f, const float2& a) { return make_float2(f/a.x, f/a.y); } -ccl_device_inline float2 operator/(const float2 a, float f) +ccl_device_inline float2 operator/(const float2& a, float f) { float invf = 1.0f/f; return make_float2(a.x*invf, a.y*invf); } -ccl_device_inline float2 operator/(const float2 a, const float2 b) +ccl_device_inline float2 operator/(const float2& a, const float2& b) { return make_float2(a.x/b.x, a.y/b.y); } -ccl_device_inline float2 operator+(const float2 a, const float2 b) +ccl_device_inline float2 operator+(const float2& a, const float2& b) { return make_float2(a.x+b.x, a.y+b.y); } -ccl_device_inline float2 operator-(const float2 a, const float2 b) +ccl_device_inline float2 operator-(const float2& a, const float2& b) { return make_float2(a.x-b.x, a.y-b.y); } -ccl_device_inline float2 operator+=(float2& a, const float2 b) +ccl_device_inline float2 operator+=(float2& a, const float2& b) { return a = a + b; } -ccl_device_inline float2 operator*=(float2& a, const float2 b) +ccl_device_inline float2 operator*=(float2& a, const float2& b) { return a = a * b; } @@ -312,7 +312,7 @@ ccl_device_inline float2 operator*=(float2& a, float f) return a = a * f; } -ccl_device_inline float2 operator/=(float2& a, const float2 b) +ccl_device_inline float2 operator/=(float2& a, const float2& b) { return a = a / b; } @@ -324,12 +324,12 @@ ccl_device_inline float2 operator/=(float2& a, float f) } -ccl_device_inline float dot(const float2 a, const float2 b) +ccl_device_inline float dot(const float2& a, const float2& b) { return a.x*b.x + a.y*b.y; } -ccl_device_inline float cross(const float2 a, const float2 b) +ccl_device_inline float cross(const float2& a, const float2& b) { return (a.x*b.y - a.y*b.x); } @@ -343,59 +343,59 @@ ccl_device_inline bool operator==(const int2 a, const int2 b) return (a.x == b.x && a.y == b.y); } -ccl_device_inline float len(const float2 a) +ccl_device_inline float len(const float2& a) { return sqrtf(dot(a, a)); } -ccl_device_inline float2 normalize(const float2 a) +ccl_device_inline float2 normalize(const float2& a) { return a/len(a); } -ccl_device_inline float2 normalize_len(const float2 a, float *t) +ccl_device_inline float2 normalize_len(const float2& a, float *t) { *t = len(a); return a/(*t); } -ccl_device_inline float2 safe_normalize(const float2 a) +ccl_device_inline float2 safe_normalize(const float2& a) { float t = len(a); return (t != 0.0f)? a/t: a; } -ccl_device_inline bool operator==(const float2 a, const float2 b) +ccl_device_inline bool operator==(const float2& a, const float2& b) { return (a.x == b.x && a.y == b.y); } -ccl_device_inline bool operator!=(const float2 a, const float2 b) +ccl_device_inline bool operator!=(const float2& a, const float2& b) { return !(a == b); } -ccl_device_inline float2 min(float2 a, float2 b) +ccl_device_inline float2 min(const float2& a, const float2& b) { return make_float2(min(a.x, b.x), min(a.y, b.y)); } -ccl_device_inline float2 max(float2 a, float2 b) +ccl_device_inline float2 max(const float2& a, const float2& b) { return make_float2(max(a.x, b.x), max(a.y, b.y)); } -ccl_device_inline float2 clamp(float2 a, float2 mn, float2 mx) +ccl_device_inline float2 clamp(const float2& a, const float2& mn, const float2& mx) { return min(max(a, mn), mx); } -ccl_device_inline float2 fabs(float2 a) +ccl_device_inline float2 fabs(const float2& a) { return make_float2(fabsf(a.x), fabsf(a.y)); } -ccl_device_inline float2 as_float2(const float4 a) +ccl_device_inline float2 as_float2(const float4& a) { return make_float2(a.x, a.y); } @@ -413,7 +413,7 @@ ccl_device_inline void print_float2(const char *label, const float2& a) #ifndef __KERNEL_OPENCL__ -ccl_device_inline float2 interp(float2 a, float2 b, float t) +ccl_device_inline float2 interp(const float2& a, const float2& b, float t) { return a + t*(b - a); } @@ -424,58 +424,92 @@ ccl_device_inline float2 interp(float2 a, float2 b, float t) #ifndef __KERNEL_OPENCL__ -ccl_device_inline float3 operator-(const float3 a) +ccl_device_inline float3 operator-(const float3& a) { +#ifdef __KERNEL_SSE__ + return float3(_mm_xor_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x80000000)))); +#else return make_float3(-a.x, -a.y, -a.z); +#endif } -ccl_device_inline float3 operator*(const float3 a, const float3 b) +ccl_device_inline float3 operator*(const float3& a, const float3& b) { +#ifdef __KERNEL_SSE__ + return float3(_mm_mul_ps(a.m128,b.m128)); +#else return make_float3(a.x*b.x, a.y*b.y, a.z*b.z); +#endif } -ccl_device_inline float3 operator*(const float3 a, float f) +ccl_device_inline float3 operator*(const float3& a, const float f) { +#ifdef __KERNEL_SSE__ + return float3(_mm_mul_ps(a.m128,_mm_set1_ps(f))); +#else return make_float3(a.x*f, a.y*f, a.z*f); +#endif } -ccl_device_inline float3 operator*(float f, const float3 a) +ccl_device_inline float3 operator*(const float f, const float3& a) { +#ifdef __KERNEL_SSE__ + return float3(_mm_mul_ps(a.m128, _mm_set1_ps(f))); +#else return make_float3(a.x*f, a.y*f, a.z*f); +#endif } -ccl_device_inline float3 operator/(float f, const float3 a) +ccl_device_inline float3 operator/(const float f, const float3& a) { - return make_float3(f/a.x, f/a.y, f/a.z); +#ifdef __KERNEL_SSE__ + __m128 rc = _mm_rcp_ps(a.m128); + return float3(_mm_mul_ps(_mm_set1_ps(f),rc)); +#else + return make_float3(f / a.x, f / a.y, f / a.z); +#endif } -ccl_device_inline float3 operator/(const float3 a, float f) +ccl_device_inline float3 operator/(const float3& a, const float f) { float invf = 1.0f/f; - return make_float3(a.x*invf, a.y*invf, a.z*invf); + return a * invf; } -ccl_device_inline float3 operator/(const float3 a, const float3 b) +ccl_device_inline float3 operator/(const float3& a, const float3& b) { - return make_float3(a.x/b.x, a.y/b.y, a.z/b.z); +#ifdef __KERNEL_SSE__ + __m128 rc = _mm_rcp_ps(b.m128); + return float3(_mm_mul_ps(a, rc)); +#else + return make_float3(a.x / b.x, a.y / b.y, a.z / b.z); +#endif } -ccl_device_inline float3 operator+(const float3 a, const float3 b) +ccl_device_inline float3 operator+(const float3& a, const float3& b) { - return make_float3(a.x+b.x, a.y+b.y, a.z+b.z); +#ifdef __KERNEL_SSE__ + return float3(_mm_add_ps(a.m128, b.m128)); +#else + return make_float3(a.x + b.x, a.y + b.y, a.z + b.z); +#endif } -ccl_device_inline float3 operator-(const float3 a, const float3 b) +ccl_device_inline float3 operator-(const float3& a, const float3& b) { - return make_float3(a.x-b.x, a.y-b.y, a.z-b.z); +#ifdef __KERNEL_SSE__ + return float3(_mm_sub_ps(a.m128, b.m128)); +#else + return make_float3(a.x - b.x, a.y - b.y, a.z - b.z); +#endif } -ccl_device_inline float3 operator+=(float3& a, const float3 b) +ccl_device_inline float3 operator+=(float3& a, const float3& b) { return a = a + b; } -ccl_device_inline float3 operator*=(float3& a, const float3 b) +ccl_device_inline float3 operator*=(float3& a, const float3& b) { return a = a * b; } @@ -485,7 +519,7 @@ ccl_device_inline float3 operator*=(float3& a, float f) return a = a * f; } -ccl_device_inline float3 operator/=(float3& a, const float3 b) +ccl_device_inline float3 operator/=(float3& a, const float3& b) { return a = a / b; } @@ -496,7 +530,7 @@ ccl_device_inline float3 operator/=(float3& a, float f) return a = a * invf; } -ccl_device_inline float dot(const float3 a, const float3 b) +ccl_device_inline float dot(const float3& a, const float3& b) { #if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__) return _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7F)); @@ -505,7 +539,16 @@ ccl_device_inline float dot(const float3 a, const float3 b) #endif } -ccl_device_inline float dot(const float4 a, const float4 b) +ccl_device_inline float dot_xy(const float3& a, const float3& b) +{ +#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__) + return _mm_cvtss_f32(_mm_hadd_ps(_mm_mul_ps(a,b),b)); +#else + return a.x*b.x + a.y*b.y; +#endif +} + +ccl_device_inline float dot(const float4& a, const float4& b) { #if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__) return _mm_cvtss_f32(_mm_dp_ps(a, b, 0xFF)); @@ -514,7 +557,7 @@ ccl_device_inline float dot(const float4 a, const float4 b) #endif } -ccl_device_inline float3 cross(const float3 a, const float3 b) +ccl_device_inline float3 cross(const float3& a, const float3& b) { float3 r = make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); return r; @@ -538,12 +581,12 @@ ccl_device_inline float len_squared(const float3 a) #ifndef __KERNEL_OPENCL__ -ccl_device_inline float len_squared(const float4 a) +ccl_device_inline float len_squared(const float4& a) { return dot(a, a); } -ccl_device_inline float3 normalize(const float3 a) +ccl_device_inline float3 normalize(const float3& a) { #if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__) __m128 norm = _mm_sqrt_ps(_mm_dp_ps(a.m128, a.m128, 0x7F)); @@ -563,13 +606,14 @@ ccl_device_inline float3 saturate3(float3 a) ccl_device_inline float3 normalize_len(const float3 a, float *t) { *t = len(a); - return a/(*t); + float x = 1.0f / *t; + return a*x; } ccl_device_inline float3 safe_normalize(const float3 a) { float t = len(a); - return (t != 0.0f)? a/t: a; + return (t != 0.0f)? a * (1.0f/t) : a; } ccl_device_inline float3 safe_normalize_len(const float3 a, float *t) @@ -580,7 +624,7 @@ ccl_device_inline float3 safe_normalize_len(const float3 a, float *t) #ifndef __KERNEL_OPENCL__ -ccl_device_inline bool operator==(const float3 a, const float3 b) +ccl_device_inline bool operator==(const float3& a, const float3& b) { #ifdef __KERNEL_SSE__ return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 7) == 7; @@ -589,12 +633,12 @@ ccl_device_inline bool operator==(const float3 a, const float3 b) #endif } -ccl_device_inline bool operator!=(const float3 a, const float3 b) +ccl_device_inline bool operator!=(const float3& a, const float3& b) { return !(a == b); } -ccl_device_inline float3 min(float3 a, float3 b) +ccl_device_inline float3 min(const float3& a, const float3& b) { #ifdef __KERNEL_SSE__ return _mm_min_ps(a.m128, b.m128); @@ -603,7 +647,7 @@ ccl_device_inline float3 min(float3 a, float3 b) #endif } -ccl_device_inline float3 max(float3 a, float3 b) +ccl_device_inline float3 max(const float3& a, const float3& b) { #ifdef __KERNEL_SSE__ return _mm_max_ps(a.m128, b.m128); @@ -612,12 +656,12 @@ ccl_device_inline float3 max(float3 a, float3 b) #endif } -ccl_device_inline float3 clamp(float3 a, float3 mn, float3 mx) +ccl_device_inline float3 clamp(const float3& a, const float3& mn, const float3& mx) { return min(max(a, mn), mx); } -ccl_device_inline float3 fabs(float3 a) +ccl_device_inline float3 fabs(const float3& a) { #ifdef __KERNEL_SSE__ __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)); @@ -670,7 +714,7 @@ ccl_device_inline float3 interp(float3 a, float3 b, float t) #ifndef __KERNEL_OPENCL__ -ccl_device_inline float3 mix(float3 a, float3 b, float t) +ccl_device_inline float3 mix(const float3& a, const float3& b, float t) { return a + t*(b - a); } @@ -833,7 +877,7 @@ ccl_device_inline int4 operator<(const float4& a, const float4& b) #endif } -ccl_device_inline int4 operator>=(float4 a, float4 b) +ccl_device_inline int4 operator>=(const float4& a, const float4& b) { #ifdef __KERNEL_SSE__ return _mm_cvtps_epi32(_mm_cmpge_ps(a.m128, b.m128)); /* todo: avoid cvt */ @@ -851,7 +895,7 @@ ccl_device_inline int4 operator<=(const float4& a, const float4& b) #endif } -ccl_device_inline bool operator==(const float4 a, const float4 b) +ccl_device_inline bool operator==(const float4& a, const float4& b) { #ifdef __KERNEL_SSE__ return (_mm_movemask_ps(_mm_cmpeq_ps(a.m128, b.m128)) & 15) == 15; @@ -893,23 +937,23 @@ ccl_device_inline float average(const float4& a) return reduce_add(a) * 0.25f; } -ccl_device_inline float len(const float4 a) +ccl_device_inline float len(const float4& a) { return sqrtf(dot(a, a)); } -ccl_device_inline float4 normalize(const float4 a) +ccl_device_inline float4 normalize(const float4& a) { return a/len(a); } -ccl_device_inline float4 safe_normalize(const float4 a) +ccl_device_inline float4 safe_normalize(const float4& a) { float t = len(a); return (t != 0.0f)? a/t: a; } -ccl_device_inline float4 min(float4 a, float4 b) +ccl_device_inline float4 min(const float4& a, const float4& b) { #ifdef __KERNEL_SSE__ return _mm_min_ps(a.m128, b.m128); @@ -918,7 +962,7 @@ ccl_device_inline float4 min(float4 a, float4 b) #endif } -ccl_device_inline float4 max(float4 a, float4 b) +ccl_device_inline float4 max(const float4& a, const float4& b) { #ifdef __KERNEL_SSE__ return _mm_max_ps(a.m128, b.m128); @@ -1190,7 +1234,7 @@ template<class A, class B> A lerp(const A& a, const A& b, const B& t) /* Triangle */ -ccl_device_inline float triangle_area(const float3 v1, const float3 v2, const float3 v3) +ccl_device_inline float triangle_area(const float3& v1, const float3& v2, const float3& v3) { return len(cross(v3 - v2, v1 - v2))*0.5f; } diff --git a/intern/cycles/util/util_simd.h b/intern/cycles/util/util_simd.h index 8d4d79068d6..f4f460d6cf6 100644 --- a/intern/cycles/util/util_simd.h +++ b/intern/cycles/util/util_simd.h @@ -455,6 +455,7 @@ CCL_NAMESPACE_END #include "util_sseb.h" #include "util_ssei.h" #include "util_ssef.h" +#include "util_avxf.h" #endif /* __UTIL_SIMD_TYPES_H__ */ diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index 6af65f88a02..a000fae4bd6 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -174,6 +174,9 @@ struct ccl_try_align(16) int3 { __forceinline int3(const __m128i a) : m128(a) {} __forceinline operator const __m128i&(void) const { return m128; } __forceinline operator __m128i&(void) { return m128; } + + int3(const int3& a) { m128 = a.m128; } + int3& operator =(const int3& a) { m128 = a.m128; return *this; } #else int x, y, z, w; #endif @@ -193,6 +196,9 @@ struct ccl_try_align(16) int4 { __forceinline int4(const __m128i a) : m128(a) {} __forceinline operator const __m128i&(void) const { return m128; } __forceinline operator __m128i&(void) { return m128; } + + int4(const int4& a) : m128(a.m128) {} + int4& operator=(const int4& a) { m128 = a.m128; return *this; } #else int x, y, z, w; #endif @@ -237,9 +243,12 @@ struct ccl_try_align(16) float3 { }; __forceinline float3() {} - __forceinline float3(const __m128 a) : m128(a) {} + __forceinline float3(const __m128& a) : m128(a) {} __forceinline operator const __m128&(void) const { return m128; } __forceinline operator __m128&(void) { return m128; } + + __forceinline float3(const float3& a) : m128(a.m128) {} + __forceinline float3& operator =(const float3& a) { m128 = a.m128; return *this; } #else float x, y, z, w; #endif @@ -259,6 +268,10 @@ struct ccl_try_align(16) float4 { __forceinline float4(const __m128 a) : m128(a) {} __forceinline operator const __m128&(void) const { return m128; } __forceinline operator __m128&(void) { return m128; } + + __forceinline float4(const float4& a) : m128(a.m128) {} + __forceinline float4& operator =(const float4& a) { m128 = a.m128; return *this; } + #else float x, y, z, w; #endif 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 fa42778b53f..f749cf82bb9 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py +++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py @@ -163,6 +163,7 @@ class SpellChecker: "runtime", "scanline", "screencast", "screenshot", "screenshots", + "seekability", "selfcollision", "shadowbuffer", "shadowbuffers", "singletexture", @@ -184,6 +185,7 @@ class SpellChecker: "timestamp", "timestamps", "timestep", "timesteps", "todo", + "tradeoff", "un", "unbake", "uncomment", diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index c2c306e5145..87bb84b5844 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -145,8 +145,12 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name= base.layers_from_view(context.space_data) base.layers[scene.active_layer] = True else: - base.layers = [True if i == scene.active_layer - else False for i in range(len(scene.layers))] + if v3d and not v3d.lock_camera_and_layers: + base.layers = [True if i == v3d.active_layer + else False for i in range(len(v3d.layers))] + else: + base.layers = [True if i == scene.active_layer + else False for i in range(len(scene.layers))] else: if v3d: base.layers_from_view(context.space_data) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index efffc90e96c..29e84336526 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -105,6 +105,7 @@ struct Object *BKE_object_lod_matob_get(struct Object *ob, struct Scene *scene); struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, bool copy_caches); struct Object *BKE_object_copy(struct Main *bmain, struct Object *ob); void BKE_object_make_local(struct Main *bmain, struct Object *ob, const bool lib_local); +void BKE_object_make_local_ex(struct Main *bmain, struct Object *ob, const bool lib_local, const bool clear_proxy); bool BKE_object_is_libdata(struct Object *ob); bool BKE_object_obdata_is_libdata(struct Object *ob); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 8168817491f..f75b3c0df85 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -3675,15 +3675,15 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, * We do it based on the specified name. */ if (gattribs->layer[b].name[0]) { - layer = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, gattribs->layer[b].name); - type = CD_TANGENT; + layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV, gattribs->layer[b].name); + type = CD_MTFACE; if (layer == -1) { layer = CustomData_get_named_layer_index(ldata, CD_MLOOPCOL, gattribs->layer[b].name); type = CD_MCOL; } if (layer == -1) { - layer = CustomData_get_named_layer_index(ldata, CD_MLOOPUV, gattribs->layer[b].name); - type = CD_MTFACE; + layer = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, gattribs->layer[b].name); + type = CD_TANGENT; } if (layer == -1) { continue; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index e917c79a92f..28177e0b488 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1575,15 +1575,6 @@ void id_clear_lib_data_ex(Main *bmain, ID *id, const bool id_in_mainlist) if ((key = BKE_key_from_id(id))) { id_clear_lib_data_ex(bmain, &key->id, id_in_mainlist); /* sigh, why are keys in Main? */ } - - if (GS(id->name) == ID_OB) { - Object *object = (Object *)id; - if (object->proxy_from != NULL) { - object->proxy_from->proxy = NULL; - object->proxy_from->proxy_group = NULL; - } - object->proxy = object->proxy_from = object->proxy_group = NULL; - } } void id_clear_lib_data(Main *bmain, ID *id) @@ -1658,7 +1649,15 @@ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged if (lib == NULL || id->lib == lib) { if (id->lib) { /* In this specific case, we do want to make ID local even if it has no local usage yet... */ - id_make_local(bmain, id, false, true); + if (GS(id->name) == ID_OB) { + /* Special case for objects because we don't want proxy pointers to be + * cleared yet. This will happen down the road in this function. + */ + BKE_object_make_local_ex(bmain, (Object*)id, true, false); + } + else { + id_make_local(bmain, id, false, true); + } } else { id->tag &= ~(LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW); @@ -1697,12 +1696,10 @@ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged if (id->newid) { bool is_local = false, is_lib = false; - BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib); - - /* Attempt to re-link appended proxy objects. This allows appending of an entire scene + /* Attempt to re-link copied proxy objects. This allows appending of an entire scene * from another blend file into this one, even when that blend file contains proxified - * armatures. Since the proxified object needs to be linked (not local), this will - * only work when the "Localize all" checkbox is disabled. + * armatures that have local references. Since the proxified object needs to be linked + * (not local), this will only work when the "Localize all" checkbox is disabled. * TL;DR: this is a dirty hack on top of an already weak feature (proxies). */ if (GS(id->name) == ID_OB && ((Object *)id)->proxy != NULL) { Object *ob = (Object *)id; @@ -1722,12 +1719,18 @@ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged id->newid->name, ob->proxy->id.name, is_local, is_lib); } else { - /* we can switch the proxy'ing from the linked-in to the made-local proxy. */ - BKE_object_make_proxy(ob_new, ob->proxy, ob->proxy_group); + /* we can switch the proxy'ing from the linked-in to the made-local proxy. + * BKE_object_make_proxy() shouldn't be used here, as it allocates memory that + * was already allocated by BKE_object_make_local_ex() (which called BKE_object_copy_ex). */ + ob_new->proxy = ob->proxy; + ob_new->proxy_group = ob->proxy_group; + ob_new->proxy_from = ob->proxy_from; + ob_new->proxy->proxy_from = ob_new; ob->proxy = ob->proxy_from = ob->proxy_group = NULL; } } + BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib); if (!is_local && !is_lib) { BKE_libblock_free(bmain, id); do_loop = true; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 85322408099..f7257b2b0dd 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1018,7 +1018,7 @@ Object *BKE_object_copy(Main *bmain, Object *ob) return BKE_object_copy_ex(bmain, ob, false); } -void BKE_object_make_local(Main *bmain, Object *ob, const bool lib_local) +void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, const bool clear_proxy) { bool is_local = false, is_lib = false; @@ -1038,6 +1038,13 @@ void BKE_object_make_local(Main *bmain, Object *ob, const bool lib_local) if (!is_lib) { id_clear_lib_data(bmain, &ob->id); BKE_id_expand_local(&ob->id); + if (clear_proxy) { + if (ob->proxy_from != NULL) { + ob->proxy_from->proxy = NULL; + ob->proxy_from->proxy_group = NULL; + } + ob->proxy = ob->proxy_from = ob->proxy_group = NULL; + } } else { Object *ob_new = BKE_object_copy(bmain, ob); @@ -1052,6 +1059,11 @@ void BKE_object_make_local(Main *bmain, Object *ob, const bool lib_local) } } +void BKE_object_make_local(Main *bmain, Object *ob, const bool lib_local) +{ + BKE_object_make_local_ex(bmain, ob, lib_local, true); +} + /* Returns true if the Object is from an external blend file (libdata) */ bool BKE_object_is_libdata(Object *ob) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index aca0c833aea..125d6962332 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -886,7 +886,7 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name) Scene *sce = (Scene *)BKE_libblock_find_name_ex(bmain, ID_SCE, name); if (sce) { BKE_scene_set_background(bmain, sce); - printf("Scene switch: '%s' in file: '%s'\n", name, bmain->name); + printf("Scene switch for render: '%s' in file: '%s'\n", name, bmain->name); return sce; } diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index f8b98ebb8b7..33e44d73894 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -350,6 +350,10 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo } offset = -min_coord - range / 2.0f; } + else if (max_coord == min_coord) { + factor = 1.0f; + offset = -min_coord; + } } BLI_assert(factor != 0.0f); if (r_offset) { diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 976b5ed1193..875522e01c6 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -184,11 +184,8 @@ static const char *ui_item_name_add_colon(const char *name, char namestr[UI_MAX_ return name; } -static int ui_item_fit(int item, int pos, int all, int available, bool is_last, int alignment, int *offset) +static int ui_item_fit(int item, int pos, int all, int available, bool is_last, int alignment) { - if (offset) - *offset = 0; - /* available == 0 is unlimited */ if (available == 0) return item; @@ -2110,7 +2107,7 @@ static void ui_litem_layout_row(uiLayout *litem) minw = ui_litem_min_width(itemw); if (w - lastw > 0) - neww = ui_item_fit(itemw, x, totw, w - lastw, !item->next, litem->alignment, NULL); + neww = ui_item_fit(itemw, x, totw, w - lastw, !item->next, litem->alignment); else neww = 0; /* no space left, all will need clamping to minimum size */ @@ -2144,12 +2141,12 @@ static void ui_litem_layout_row(uiLayout *litem) if (item->flag) { /* fixed minimum size items */ - itemw = ui_item_fit(minw, fixedx, fixedw, min_ii(w, fixedw), !item->next, litem->alignment, NULL); + itemw = ui_item_fit(minw, fixedx, fixedw, min_ii(w, fixedw), !item->next, litem->alignment); fixedx += itemw; } else { /* free size item */ - itemw = ui_item_fit(itemw, freex, freew, w - fixedw, !item->next, litem->alignment, NULL); + itemw = ui_item_fit(itemw, freex, freew, w - fixedw, !item->next, litem->alignment); freex += itemw; } @@ -2469,7 +2466,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem) uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; uiItem *item; int col, x, y, w, emh, emy, miny, itemw, itemh; - int toth, totitem, offset; + int toth, totitem; /* compute max needed width and total height */ toth = 0; @@ -2491,22 +2488,27 @@ static void ui_litem_layout_column_flow(uiLayout *litem) /* create column per column */ col = 0; + w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol; for (item = litem->items.first; item; item = item->next) { - ui_item_size(item, NULL, &itemh); - itemw = ui_item_fit(1, x - litem->x, flow->totcol, w, col == flow->totcol - 1, litem->alignment, &offset); - + ui_item_size(item, &itemw, &itemh); + + itemw = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, itemw); + y -= itemh; emy -= itemh; - ui_item_position(item, x + offset, y, itemw, itemh); + ui_item_position(item, x, y, itemw, itemh); y -= style->buttonspacey; miny = min_ii(miny, y); /* decide to go to next one */ if (col < flow->totcol - 1 && emy <= -emh) { - x += itemw + style->columnspace; + x += w + style->columnspace; y = litem->y; emy = 0; /* need to reset height again for next column */ col++; + + /* (< remaining width > - < space between remaining columns >) / <remamining columns > */ + w = ((litem->w - (x - litem->x)) - (flow->totcol - col - 1) * style->columnspace) / (flow->totcol - col); } } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 233406333f2..9d9cae6f347 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -2767,6 +2767,10 @@ void init_userdef_do_versions(void) for (btheme = U.themes.first; btheme; btheme = btheme->next) { rgba_char_args_set(btheme->tv3d.vertex_bevel, 0, 165, 255, 255); rgba_char_args_set(btheme->tv3d.edge_bevel, 0, 165, 255, 255); + + /* 3dView Keyframe Indicators */ + btheme->tv3d.time_keyframe[3] = 0xFF; + btheme->tv3d.time_gp_keyframe[3] = 0xFF; } } diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 6f3694d1db8..0716c062ab9 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -442,7 +442,7 @@ static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, Rende if (BLI_listbase_is_empty(&gpd->layers)) { return; } - if ((oglrender->v3d->flag2 & V3D_SHOW_GPENCIL) == 0) { + if (oglrender->v3d != NULL && (oglrender->v3d->flag2 & V3D_SHOW_GPENCIL) == 0) { return; } diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 72034b4f828..631ff06a77a 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -518,14 +518,18 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) CFURLEnumeratorRef volEnum = CFURLEnumeratorCreateForMountedVolumes(NULL, kCFURLEnumeratorSkipInvisibles, NULL); while (result != kCFURLEnumeratorEnd) { - unsigned char defPath[FILE_MAX]; + char defPath[FILE_MAX]; result = CFURLEnumeratorGetNextURL(volEnum, &cfURL, NULL); if (result != kCFURLEnumeratorSuccess) continue; CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, NULL, FS_INSERT_SORTED); + + /* Add end slash for consistency with other platforms */ + BLI_add_slash(defPath); + + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, defPath, NULL, FS_INSERT_SORTED); } CFRelease(volEnum); diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index d378ca9a78c..a40b257b75b 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -522,9 +522,9 @@ static int startffmpeg(struct anim *anim) anim->duration = pFormatCtx->streams[videoStream]->nb_frames; } else { - anim->duration = ceil(pFormatCtx->duration * - av_q2d(frame_rate) / - AV_TIME_BASE); + anim->duration = (int)(pFormatCtx->duration * + av_q2d(frame_rate) / + AV_TIME_BASE + 0.5f); } frs_num = frame_rate.num; diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 9b881c13347..7ba89538b18 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -783,6 +783,16 @@ static void rna_GPencilPalette_info_set(PointerRNA *ptr, const char *value) sizeof(palette->info)); } +static char *rna_GPencilPalette_path(PointerRNA *ptr) +{ + bGPDpalette *palette = ptr->data; + char name_esc[sizeof(palette->info) * 2]; + + BLI_strescape(name_esc, palette->info, sizeof(name_esc)); + + return BLI_sprintfN("palettes[\"%s\"]", name_esc); +} + static char *rna_GPencilPalette_color_path(PointerRNA *ptr) { bGPdata *gpd = ptr->id.data; @@ -1510,6 +1520,7 @@ static void rna_def_gpencil_palette(BlenderRNA *brna) srna = RNA_def_struct(brna, "GPencilPalette", NULL); RNA_def_struct_sdna(srna, "bGPDpalette"); RNA_def_struct_ui_text(srna, "Grease Pencil Palette", "Collection of related palettes"); + RNA_def_struct_path_func(srna, "rna_GPencilPalette_path"); RNA_def_struct_ui_icon(srna, ICON_COLOR); /* Name */ diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index b0be30ac355..6baf2f3631d 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -729,7 +729,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "draw_velocity", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "draw_velocity", 0); - RNA_def_property_ui_text(prop, "Draw Velocity", "Toggle visualation of the velocity field as needles"); + RNA_def_property_ui_text(prop, "Draw Velocity", "Toggle visualization of the velocity field as needles"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); prop = RNA_def_property(srna, "vector_draw_type", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 9eaff19770a..04b8942ecb9 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -520,6 +520,13 @@ static void rna_SpaceView3D_layer_set(PointerRNA *ptr, const int *values) v3d->lay = ED_view3d_scene_layer_set(v3d->lay, values, &v3d->layact); } +static int rna_SpaceView3D_active_layer_get(PointerRNA *ptr) +{ + View3D *v3d = (View3D *)(ptr->data); + + return (int)(log(v3d->layact) / M_LN2); +} + static void rna_SpaceView3D_layer_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { DAG_on_visible_update(bmain, false); @@ -2637,6 +2644,11 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Visible Layers", "Layers visible in this 3D View"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_layer_update"); + prop = RNA_def_property(srna, "active_layer", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); + RNA_def_property_int_funcs(prop, "rna_SpaceView3D_active_layer_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Active Layer", "Active 3D view layer index"); + prop = RNA_def_property(srna, "layers_local_view", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "lay", 0x01000000); RNA_def_property_array(prop, 8); diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 8523b7275bf..40d1cfdfcb0 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -327,7 +327,8 @@ static void ntree_shader_link_builtin_group_normal( /* Need to update tree so all node instances nodes gets proper sockets. */ bNode *group_input_node = ntreeFindType(group_ntree, NODE_GROUP_INPUT); node_group_verify(ntree, group_node, &group_ntree->id); - node_group_input_verify(group_ntree, group_input_node, &group_ntree->id); + if (group_input_node) + node_group_input_verify(group_ntree, group_input_node, &group_ntree->id); ntreeUpdateTree(G.main, group_ntree); /* Assumes sockets are always added at the end. */ bNodeSocket *group_node_normal_socket = group_node->inputs.last; @@ -370,7 +371,7 @@ static void ntree_shader_link_builtin_group_normal( group_displacement_socket); ntreeUpdateTree(G.main, group_ntree); } - else { + else if (group_input_node) { /* Connect group node normal input. */ nodeAddLink(ntree, node_from, socket_from, diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 33f12927f2b..a132d323a8c 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2875,8 +2875,8 @@ void WM_OT_straightline_gesture(wmOperatorType *ot) /* *********************** radial control ****************** */ -#define WM_RADIAL_CONTROL_DISPLAY_SIZE (200) -#define WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE (35) +#define WM_RADIAL_CONTROL_DISPLAY_SIZE (200 * UI_DPI_FAC) +#define WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE (35 * UI_DPI_FAC) #define WM_RADIAL_CONTROL_DISPLAY_WIDTH (WM_RADIAL_CONTROL_DISPLAY_SIZE - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE) #define WM_RADIAL_MAX_STR 10 @@ -3153,7 +3153,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd if (rmin > 0.0f) glutil_draw_lined_arc(0.0, (float)(M_PI * 2.0), rmin, 40); - BLF_size(fontid, 1.5 * fstyle_points, 1.0f / U.dpi); + BLF_size(fontid, 1.5 * fstyle_points * U.pixelsize, U.dpi); BLF_enable(fontid, BLF_SHADOW); BLF_shadow(fontid, 3, (const float[4]){0.0f, 0.0f, 0.0f, 0.5f}); BLF_shadow_offset(fontid, 1, -1); |