Merge remote-tracking branch 'origin/master' into blender2.8
authorDalai Felinto <dfelinto@gmail.com>
Thu, 13 Oct 2016 16:42:54 +0000 (16:42 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Thu, 13 Oct 2016 16:42:54 +0000 (16:42 +0000)
31 files changed:
doc/python_api/sphinx_changelog_gen.py
doc/python_api/sphinx_doc_gen.py
intern/cycles/kernel/geom/geom_triangle_intersect.h
intern/cycles/kernel/kernel_compat_cpu.h
intern/cycles/kernel/kernel_subsurface.h
intern/cycles/kernel/kernels/cpu/kernel.cpp
intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp
intern/cycles/render/graph.cpp
intern/cycles/util/CMakeLists.txt
intern/cycles/util/util_avxf.h [new file with mode: 0644]
intern/cycles/util/util_math.h
intern/cycles/util/util_simd.h
intern/cycles/util/util_types.h
release/scripts/modules/bl_i18n_utils/utils_spell_check.py
release/scripts/modules/bpy_extras/object_utils.py
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/scene.c
source/blender/editors/animation/anim_draw.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/resources.c
source/blender/editors/render/render_opengl.c
source/blender/editors/space_file/fsmenu.c
source/blender/imbuf/intern/anim_movie.c
source/blender/makesrna/intern/rna_gpencil.c
source/blender/makesrna/intern/rna_smoke.c
source/blender/makesrna/intern/rna_space.c
source/blender/nodes/shader/node_shader_tree.c
source/blender/windowmanager/intern/wm_operators.c

index 4cbb418e326fe788ca376cbb4cfdc1d0bc1a8109..8758590dbaea1b753a137aa2da23439e2b7e190b 100644 (file)
@@ -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"
 
index 4a109a44ec0742034bfe097401ec5363b596100e..2fbbd16a4618197118221f02fe900ac26ed1092e 100644 (file)
@@ -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.
index dd5328220ab43213f3df2c63ec11b90992916df2..b505bd54e5e54606819026c6a0ce16b059838261 100644 (file)
@@ -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;
index 7b30df045503dff5c1f280a972ef0ffd0d21a2d8..9d1f3bdc9185208f504cc54a13bc8c8663134489 100644 (file)
@@ -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))
index f03fe288a0c9554539a071ea105920d356910e6d..52c05b85aee356dd245ab7d944efbf74b87a6def 100644 (file)
@@ -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,
-        SubsurfaceIntersectionss_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) {
index f11c85d5f6a2a7771421fda504450a3883c7acdc..1559b0d7322f476366eaa6a016f93bef85289b62 100644 (file)
@@ -45,6 +45,7 @@
 #    define __KERNEL_AVX__
 #  endif
 #  ifdef __AVX2__
+#    define __KERNEL_SSE__
 #    define __KERNEL_AVX2__
 #  endif
 #endif
index 7351e2bad6b312397d9366632cee7c44028306de..1a416e771ee212274b6e1adb10a14c1a1cdf3708 100644 (file)
@@ -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__
index ed8c7056aaa1213e272253fbf069a46bdf701eb7..131ec824be3d8d6582d40e6022a0b0bd3be1508f 100644 (file)
@@ -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)
index f5674bdc15ccac00f9ecfc5132c6892956f6f565..02ee4cd67744137ceb0e31fa1844b179991dc721 100644 (file)
@@ -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 (file)
index 0000000..2db2c4d
--- /dev/null
@@ -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
index 89a882d9b9dd5430f9c1682070966256c90f3fed..ce2e4e5c30dcabcc1d74bb13e40dc407fef9527e 100644 (file)
@@ -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;
 }
index 8d4d79068d626326d945d713bb6d34a833a33f93..f4f460d6cf668ef5a161c8c336d4bd574a1d9688 100644 (file)
@@ -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__ */
 
index 6af65f88a0255685e6f050a00f1853e0d88e3609..a000fae4bd668baa94dd8fd0f8689035a5785db8 100644 (file)
@@ -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
index fa42778b53f3942ee752d7affed9229dc7fd106e..f749cf82bb9ae392fb0018471c9a52db98137aa4 100644 (file)
@@ -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",
index c2c306e5145fb5f6958064d26e4b7429152f8e7d..87bb84b5844a448cb6f096ba167853b76b75926c 100644 (file)
@@ -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)
index efffc90e96c418ba5a58d03ad01a9c674f885a5d..29e8433652666c6129dee1396fc0f24977567625 100644 (file)
@@ -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);
 
index 8168817491fac073054ff497c57081dfa150d105..f75b3c0df85e7f8fa68bb7bdea9550f4da6fa252 100644 (file)
@@ -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;
index e917c79a92fb27fabe5399904f22ae07901b03b7..28177e0b488651352332010e3456021bebf0804c 100644 (file)
@@ -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;
index 853224080990740fdb54e44b58e7825db61c8777..f7257b2b0dde94558d3d639de8390ac1d10a0233 100644 (file)
@@ -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)
 {
index aca0c833aea82879d80618146f5142c1a2230477..125d6962332ba6fad6da3c090f85f8e7190aa129 100644 (file)
@@ -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;
        }
 
index f8b98ebb8b72ff8de1b8e74a974de45b84650260..33e44d738945bfe9036828c180b08e337c535c4c 100644 (file)
@@ -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) {
index 976b5ed1193d421dbc7c79eef59b5d1610bd9595..875522e01c6b25d2e6c2f03fa0985f891eb28c05 100644 (file)
@@ -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);
                }
        }
 
index 233406333f2c7a2a572dc4873fc9ada45f26ccfa..9d9cae6f347d1ba0889735c84faeeb848894abdb 100644 (file)
@@ -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;
                }
        }
 
index 6f3694d1db8663f2faf9c4e1b5fd7b11fc3a0fac..0716c062ab9c677ac5681ae045326e53c588db1a 100644 (file)
@@ -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;
        }
 
index 72034b4f828f7f53c6b048e7a321333167e4560d..631ff06a77ad1a0c640d63da6345b3b074a45d98 100644 (file)
@@ -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);
index d378ca9a78c826260ff5b0ede484dbf04c9baa1a..a40b257b75b14c830a7b3bcb7c304d61c932746c 100644 (file)
@@ -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;
index 9b881c13347a9b8477626759da36849227d128db..7ba89538b1834f41bedb1d70b0051039784d2d1c 100644 (file)
@@ -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 */
index b0be30ac3555bd02dedee067036203fda836bde8..6baf2f3631d3110bd08d05be4664db1ea465e62d 100644 (file)
@@ -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);
index 9eaff19770ae307e1b315dc60dd7d31d27a7b6ad..04b8942ecb9e6e202eb11d12b462614c46dd42b0 100644 (file)
@@ -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);
index 8523b7275bfcbdce984a45e1884904680630e186..40d1cfdfcb0adbec4c218690d63c384510ca8492 100644 (file)
@@ -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,
index 33f12927f2b13bb2a2cfbafbb77aef4d89cba89d..a132d323a8c2db128a52ce2e24546d202a025aa0 100644 (file)
@@ -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);