Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-07-28 05:00:58 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-07-28 05:00:58 +0300
commit251349c3c2269fff915d1bb85911211563493071 (patch)
tree35524bdb77d583562227ee11b1ff516ea278e00e
parentb1532493c27b08444745cef348641f3a0e899ba8 (diff)
parenta27acefd0c89aab63a6c243a844e2790dfad961a (diff)
Merge branch 'master' into blender2.8
-rwxr-xr-xbuild_files/package_spec/build_archive.py2
-rwxr-xr-xdoc/manpage/blender.1.py2
-rw-r--r--extern/curve_fit_nd/intern/curve_fit_cubic_refit.c4
-rw-r--r--intern/cycles/kernel/bvh/bvh_shadow_all.h12
-rw-r--r--intern/cycles/kernel/bvh/bvh_volume_all.h18
-rw-r--r--intern/cycles/kernel/bvh/qbvh_shadow_all.h11
-rw-r--r--intern/cycles/kernel/bvh/qbvh_volume_all.h18
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h34
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h26
-rw-r--r--intern/cycles/kernel/kernel_shadow.h7
-rw-r--r--intern/cycles/kernel/kernel_volume.h4
-rw-r--r--intern/cycles/render/light.cpp18
-rw-r--r--intern/cycles/render/nodes.cpp4
-rw-r--r--intern/cycles/render/nodes.h4
-rw-r--r--intern/opensubdiv/gpu_shader_opensubd_display.glsl4
-rw-r--r--intern/opensubdiv/opensubdiv_gpu_capi.cc82
-rwxr-xr-xrelease/bin/blender-thumbnailer.py2
-rwxr-xr-xrelease/datafiles/ctodata.py2
-rwxr-xr-xrelease/scripts/modules/blend_render_info.py2
-rw-r--r--source/blender/blenkernel/BKE_library.h1
-rw-r--r--source/blender/blenkernel/intern/action.c5
-rw-r--r--source/blender/blenkernel/intern/armature.c5
-rw-r--r--source/blender/blenkernel/intern/brush.c5
-rw-r--r--source/blender/blenkernel/intern/camera.c5
-rw-r--r--source/blender/blenkernel/intern/curve.c5
-rw-r--r--source/blender/blenkernel/intern/group.c5
-rw-r--r--source/blender/blenkernel/intern/image.c5
-rw-r--r--source/blender/blenkernel/intern/key.c5
-rw-r--r--source/blender/blenkernel/intern/lamp.c5
-rw-r--r--source/blender/blenkernel/intern/lattice.c5
-rw-r--r--source/blender/blenkernel/intern/library.c11
-rw-r--r--source/blender/blenkernel/intern/library_query.c8
-rw-r--r--source/blender/blenkernel/intern/linestyle.c5
-rw-r--r--source/blender/blenkernel/intern/mask.c5
-rw-r--r--source/blender/blenkernel/intern/material.c5
-rw-r--r--source/blender/blenkernel/intern/mball.c5
-rw-r--r--source/blender/blenkernel/intern/mesh.c5
-rw-r--r--source/blender/blenkernel/intern/node.c5
-rw-r--r--source/blender/blenkernel/intern/object.c5
-rw-r--r--source/blender/blenkernel/intern/smoke.c3
-rw-r--r--source/blender/blenkernel/intern/speaker.c5
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c18
-rw-r--r--source/blender/blenkernel/intern/text.c5
-rw-r--r--source/blender/blenkernel/intern/texture.c5
-rw-r--r--source/blender/blenkernel/intern/world.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h4
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc4
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_eval.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc22
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.h2
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.cc2
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.h2
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.cc2
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.h2
-rw-r--r--source/blender/editors/curve/editcurve_paint.c4
-rw-r--r--source/blender/editors/include/UI_interface.h6
-rw-r--r--source/blender/editors/interface/interface_handlers.c4
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_regions.c32
-rw-r--r--source/blender/editors/render/render_preview.c2
-rw-r--r--source/blender/editors/space_clip/space_clip.c2
-rw-r--r--source/blender/editors/space_node/node_group.c45
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c4
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c6
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h1
-rw-r--r--source/blender/gpu/intern/gpu_material.c3
-rw-r--r--source/blender/makesdna/DNA_screen_types.h17
-rw-r--r--source/blender/makesrna/intern/rna_ID.c6
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c14
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c5
72 files changed, 363 insertions, 237 deletions
diff --git a/build_files/package_spec/build_archive.py b/build_files/package_spec/build_archive.py
index 6a7ec8a0faa..bd00984c74b 100755
--- a/build_files/package_spec/build_archive.py
+++ b/build_files/package_spec/build_archive.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# <pep8 compliant>
diff --git a/doc/manpage/blender.1.py b/doc/manpage/blender.1.py
index cdd2d7ca2df..52856717b4a 100755
--- a/doc/manpage/blender.1.py
+++ b/doc/manpage/blender.1.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
diff --git a/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c b/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c
index 46445467869..c78b79d76ef 100644
--- a/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c
+++ b/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c
@@ -43,6 +43,10 @@
* While re-fitting, remove knots that fall below the error threshold.
*/
+#ifdef _MSC_VER
+# define _USE_MATH_DEFINES
+#endif
+
#include <math.h>
#include <float.h>
#include <stdbool.h>
diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h
index b27afaa9869..1d6fa303d3e 100644
--- a/intern/cycles/kernel/bvh/bvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h
@@ -254,9 +254,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
/* shadow ray early termination */
if(hit) {
- /* Update number of hits now, so we do proper check on max bounces. */
- (*num_hits)++;
-
/* detect if this surface has a shader with transparent shadows */
/* todo: optimize so primitive visibility flag indicates if
@@ -283,15 +280,18 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
return true;
}
/* if maximum number of hits reached, block all light */
- else if(*num_hits >= max_hits) {
+ else if(*num_hits == max_hits) {
return true;
}
+ /* move on to next entry in intersections array */
+ isect_array++;
+ (*num_hits)++;
#if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++;
#endif
- /* Move on to next entry in intersections array */
- isect_array++;
+
+ isect_array->t = isect_t;
}
prim_addr++;
diff --git a/intern/cycles/kernel/bvh/bvh_volume_all.h b/intern/cycles/kernel/bvh/bvh_volume_all.h
index d7f6bf86c71..7eddc2891d0 100644
--- a/intern/cycles/kernel/bvh/bvh_volume_all.h
+++ b/intern/cycles/kernel/bvh/bvh_volume_all.h
@@ -201,12 +201,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
object,
prim_addr);
if(hit) {
- /* Update number of hits now, so we do proper check on max bounces. */
+ /* Move on to next entry in intersections array. */
+ isect_array++;
num_hits++;
#if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++;
#endif
- if(num_hits >= max_hits) {
+ isect_array->t = isect_t;
+ if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
@@ -220,9 +222,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
#endif /* BVH_FEATURE(BVH_INSTANCING) */
return num_hits;
}
- /* Move on to next entry in intersections array */
- isect_array++;
- isect_array->t = isect_t;
}
}
break;
@@ -247,12 +246,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
object,
prim_addr);
if(hit) {
- /* Update number of hits now, so we do proper check on max bounces. */
+ /* Move on to next entry in intersections array. */
+ isect_array++;
num_hits++;
# if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++;
# endif
- if(num_hits >= max_hits) {
+ isect_array->t = isect_t;
+ if(num_hits == max_hits) {
# if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
@@ -266,9 +267,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
# endif /* BVH_FEATURE(BVH_INSTANCING) */
return num_hits;
}
- /* Move on to next entry in intersections array */
- isect_array++;
- isect_array->t = isect_t;
}
}
break;
diff --git a/intern/cycles/kernel/bvh/qbvh_shadow_all.h b/intern/cycles/kernel/bvh/qbvh_shadow_all.h
index eb98eaf7455..3a728b388eb 100644
--- a/intern/cycles/kernel/bvh/qbvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/qbvh_shadow_all.h
@@ -337,9 +337,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Shadow ray early termination. */
if(hit) {
- /* Update number of hits now, so we do proper check on max bounces. */
- (*num_hits)++;
-
/* detect if this surface has a shader with transparent shadows */
/* todo: optimize so primitive visibility flag indicates if
@@ -366,15 +363,17 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
return true;
}
/* if maximum number of hits reached, block all light */
- else if(*num_hits >= max_hits) {
+ else if(*num_hits == max_hits) {
return true;
}
+ /* move on to next entry in intersections array */
+ isect_array++;
+ (*num_hits)++;
#if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++;
#endif
- /* Move on to next entry in intersections array */
- isect_array++;
+
isect_array->t = isect_t;
}
diff --git a/intern/cycles/kernel/bvh/qbvh_volume_all.h b/intern/cycles/kernel/bvh/qbvh_volume_all.h
index 90cad9d91c0..4d3028b37bf 100644
--- a/intern/cycles/kernel/bvh/qbvh_volume_all.h
+++ b/intern/cycles/kernel/bvh/qbvh_volume_all.h
@@ -268,12 +268,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Intersect ray against primitive. */
hit = triangle_intersect(kg, &isect_precalc, isect_array, P, visibility, object, prim_addr);
if(hit) {
- /* Update number of hits now, so we do proper check on max bounces. */
+ /* Move on to next entry in intersections array. */
+ isect_array++;
num_hits++;
#if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++;
#endif
- if(num_hits >= max_hits) {
+ isect_array->t = isect_t;
+ if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
@@ -287,9 +289,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
#endif /* BVH_FEATURE(BVH_INSTANCING) */
return num_hits;
}
- /* Move on to next entry in intersections array */
- isect_array++;
- isect_array->t = isect_t;
}
}
break;
@@ -307,12 +306,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Intersect ray against primitive. */
hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
if(hit) {
- /* Update number of hits now, so we do proper check on max bounces. */
+ /* Move on to next entry in intersections array. */
+ isect_array++;
num_hits++;
# if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++;
# endif
- if(num_hits >= max_hits) {
+ isect_array->t = isect_t;
+ if(num_hits == max_hits) {
# if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION)
float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
@@ -326,9 +327,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
# endif /* BVH_FEATURE(BVH_INSTANCING) */
return num_hits;
}
- /* Move on to next entry in intersections array */
- isect_array++;
- isect_array->t = isect_t;
}
}
break;
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index 51b12fe4e45..acb50ce6faa 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -42,7 +42,7 @@ ccl_device_inline float D_ggx_aniso(const float3 wm, const float2 alpha)
/* Sample slope distribution (based on page 14 of the supplemental implementation). */
ccl_device_inline float2 mf_sampleP22_11(const float cosI, const float2 randU)
{
- if(cosI > 0.9999f) {
+ if(cosI > 0.9999f || cosI < 1e-6f) {
const float r = sqrtf(randU.x / (1.0f - randU.x));
const float phi = M_2PI_F * randU.y;
return make_float2(r*cosf(phi), r*sinf(phi));
@@ -117,7 +117,7 @@ ccl_device_inline float3 mf_eval_phase_glossy(const float3 w, const float lambda
if(dotW_WH < 0.0f)
return make_float3(0.0f, 0.0f, 0.0f);
- float phase = max(0.0f, dotW_WH) * 0.25f / (pArea * dotW_WH);
+ float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f);
if(alpha.x == alpha.y)
phase *= D_ggx(wh, alpha.x);
else
@@ -200,9 +200,9 @@ ccl_device_inline float mf_lambda(const float3 w, const float2 alpha)
if(w.z > 0.9999f)
return 0.0f;
else if(w.z < -0.9999f)
- return -1.0f;
+ return -0.9999f;
- const float inv_wz2 = 1.0f / (w.z*w.z);
+ const float inv_wz2 = 1.0f / max(w.z*w.z, 1e-7f);
const float2 wa = make_float2(w.x, w.y)*alpha;
float v = sqrtf(1.0f + dot(wa, wa) * inv_wz2);
if(w.z <= 0.0f)
@@ -271,7 +271,10 @@ ccl_device_inline float mf_ggx_albedo(float r)
ccl_device_inline float mf_ggx_pdf(const float3 wi, const float3 wo, const float alpha)
{
- return 0.25f * D_ggx(normalize(wi+wo), alpha) / ((1.0f + mf_lambda(wi, make_float2(alpha, alpha))) * wi.z) + (1.0f - mf_ggx_albedo(alpha)) * wo.z;
+ float D = D_ggx(normalize(wi+wo), alpha);
+ float lambda = mf_lambda(wi, make_float2(alpha, alpha));
+ float albedo = mf_ggx_albedo(alpha);
+ return 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f) + (1.0f - albedo) * wo.z;
}
ccl_device_inline float mf_ggx_aniso_pdf(const float3 wi, const float3 wo, const float2 alpha)
@@ -406,6 +409,10 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg, const ShaderC
*eval *= *pdf;
*omega_in = X*localO.x + Y*localO.y + Z*localO.z;
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
+ *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
+#endif
return LABEL_REFLECT|LABEL_GLOSSY;
}
@@ -463,10 +470,23 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg, const S
*eval *= *pdf;
*omega_in = X*localO.x + Y*localO.y + Z*localO.z;
- if(localO.z*localI.z > 0.0f)
+ if(localO.z*localI.z > 0.0f) {
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
+ *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
+#endif
return LABEL_REFLECT|LABEL_GLOSSY;
- else
+ }
+ else {
+#ifdef __RAY_DIFFERENTIALS__
+ float cosI = dot(Z, I);
+ float dnp = max(sqrtf(1.0f - (sc->data2 * sc->data2 * (1.0f - cosI*cosI))), 1e-7f);
+ *domega_in_dx = -(sc->data2 * dIdx) + ((sc->data2 - sc->data2 * sc->data2 * cosI / dnp) * dot(dIdx, Z)) * Z;
+ *domega_in_dy = -(sc->data2 * dIdy) + ((sc->data2 - sc->data2 * sc->data2 * cosI / dnp) * dot(dIdy, Z)) * Z;
+#endif
+
return LABEL_TRANSMIT|LABEL_GLOSSY;
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index caa6c9d9a5b..eb0decc800b 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -342,9 +342,16 @@ ccl_device_inline float3 triangle_refine(KernelGlobals *kg,
float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
float3 qvec = cross(tvec, edge1);
float3 pvec = cross(D, edge2);
- float rt = dot(edge2, qvec) / dot(edge1, pvec);
-
- P = P + D*rt;
+ float det = dot(edge1, pvec);
+ if(det != 0.0f) {
+ /* If determinant is zero it means ray lies in the plane of
+ * the triangle. It is possible in theory due to watertight
+ * nature of triangle intersection. For suc hcases we simply
+ * don't refine intersection hoping it'll go all fine.
+ */
+ float rt = dot(edge2, qvec) / det;
+ P = P + D*rt;
+ }
if(isect->object != OBJECT_NONE) {
# ifdef __OBJECT_MOTION__
@@ -400,9 +407,16 @@ ccl_device_inline float3 triangle_refine_subsurface(KernelGlobals *kg,
float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
float3 qvec = cross(tvec, edge1);
float3 pvec = cross(D, edge2);
- float rt = dot(edge2, qvec) / dot(edge1, pvec);
-
- P = P + D*rt;
+ float det = dot(edge1, pvec);
+ if(det != 0.0f) {
+ /* If determinant is zero it means ray lies in the plane of
+ * the triangle. It is possible in theory due to watertight
+ * nature of triangle intersection. For such cases we simply
+ * don't refine intersection hoping it'll go all fine.
+ */
+ float rt = dot(edge2, qvec) / det;
+ P = P + D*rt;
+ }
#endif /* __INTERSECTION_REFINE__ */
if(isect->object != OBJECT_NONE) {
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index d1576754d2e..db2fc84834a 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -75,12 +75,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, ShaderData *shadow_sd,
}
uint num_hits;
- if(max_hits == 0) {
- blocked = true;
- num_hits = 0;
- } else {
- blocked = scene_intersect_shadow_all(kg, ray, hits, max_hits, &num_hits);
- }
+ blocked = scene_intersect_shadow_all(kg, ray, hits, max_hits, &num_hits);
/* if no opaque surface found but we did find transparent hits, shade them */
if(!blocked && num_hits > 0) {
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index bf8301fe5fb..01c87e6d89d 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -1029,7 +1029,7 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg,
int stack_index = 0, enclosed_index = 0;
#ifdef __VOLUME_RECORD_ALL__
- Intersection hits[2*VOLUME_STACK_SIZE];
+ Intersection hits[2*VOLUME_STACK_SIZE + 1];
uint num_hits = scene_intersect_volume_all(kg,
&volume_ray,
hits,
@@ -1199,7 +1199,7 @@ ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *kg,
Ray volume_ray = *ray;
# ifdef __VOLUME_RECORD_ALL__
- Intersection hits[2*VOLUME_STACK_SIZE];
+ Intersection hits[2*VOLUME_STACK_SIZE + 1];
uint num_hits = scene_intersect_volume_all(kg,
&volume_ray,
hits,
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 9ef35820254..6a1437fefb9 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -443,9 +443,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
device->tex_alloc("__light_distribution", dscene->light_distribution);
/* Portals */
- if(num_background_lights > 0 && light_index != scene->lights.size()) {
+ if(num_background_lights > 0 && light_index != num_lights) {
kintegrator->portal_offset = light_index;
- kintegrator->num_portals = scene->lights.size() - light_index;
+ kintegrator->num_portals = num_lights - light_index;
kintegrator->portal_pdf = background_mis? 0.5f: 1.0f;
}
else {
@@ -609,10 +609,20 @@ void LightManager::device_update_points(Device *device,
Scene *scene)
{
int num_scene_lights = scene->lights.size();
- if(num_scene_lights == 0)
+ int num_lights = 0;
+
+ foreach(Light *light, scene->lights) {
+ if(light->is_enabled) {
+ num_lights++;
+ }
+ }
+
+
+ float4 *light_data = dscene->light_data.resize(num_lights*LIGHT_SIZE);
+
+ if(num_lights == 0)
return;
- float4 *light_data = dscene->light_data.resize(num_scene_lights*LIGHT_SIZE);
int light_index = 0;
foreach(Light *light, scene->lights) {
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index e26084c690b..ed4debdddfc 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2323,7 +2323,7 @@ NODE_DEFINE(EmissionNode)
NodeType* type = NodeType::add("emission", create, NodeType::SHADER);
SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
- SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
+ SOCKET_IN_FLOAT(strength, "Strength", 10.0f);
SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
SOCKET_OUT_CLOSURE(emission, "Emission");
@@ -2344,7 +2344,7 @@ void EmissionNode::compile(SVMCompiler& compiler)
if(color_in->link || strength_in->link) {
compiler.add_node(NODE_EMISSION_WEIGHT,
compiler.stack_assign(color_in),
- compiler.stack_assign(strength_in));
+ compiler.stack_assign(strength_in));
}
else
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index caad11af0f8..79d25d01176 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -152,8 +152,8 @@ class OutputNode : public ShaderNode {
public:
SHADER_NODE_CLASS(OutputNode)
- void* surface;
- void* volume;
+ void *surface;
+ void *volume;
float displacement;
float3 normal;
diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
index cc9e05a11c8..5193d3a71dc 100644
--- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
@@ -242,6 +242,7 @@ void main()
vec3 L_diffuse = vec3(0.0);
vec3 L_specular = vec3(0.0);
+#ifdef USE_LIGHTING
#ifndef USE_COLOR_MATERIAL
/* Assume NUM_SOLID_LIGHTS directional lights. */
for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
@@ -312,6 +313,9 @@ void main()
L_specular += light_specular * specular_bsdf * intensity;
}
#endif /* USE_COLOR_MATERIAL */
+#else /* USE_LIGHTING */
+ L_diffuse = vec3(1.0);
+#endif
/* Compute diffuse color. */
#ifdef USE_TEXTURE_2D
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 752dce7744c..0cf6fcfef43 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -100,6 +100,12 @@ static GLuint g_flat_fill_solid_program = 0;
static GLuint g_flat_fill_texture2d_program = 0;
static GLuint g_smooth_fill_solid_program = 0;
static GLuint g_smooth_fill_texture2d_program = 0;
+
+static GLuint g_flat_fill_solid_shadeless_program = 0;
+static GLuint g_flat_fill_texture2d_shadeless_program = 0;
+static GLuint g_smooth_fill_solid_shadeless_program = 0;
+static GLuint g_smooth_fill_texture2d_shadeless_program = 0;
+
static GLuint g_wireframe_program = 0;
static GLuint g_lighting_ub = 0;
@@ -425,21 +431,45 @@ bool openSubdiv_osdGLDisplayInit(void)
g_flat_fill_solid_program = linkProgram(
version,
"#define USE_COLOR_MATERIAL\n"
+ "#define USE_LIGHTING\n"
"#define FLAT_SHADING\n");
g_flat_fill_texture2d_program = linkProgram(
version,
"#define USE_COLOR_MATERIAL\n"
+ "#define USE_LIGHTING\n"
"#define USE_TEXTURE_2D\n"
"#define FLAT_SHADING\n");
g_smooth_fill_solid_program = linkProgram(
version,
"#define USE_COLOR_MATERIAL\n"
+ "#define USE_LIGHTING\n"
"#define SMOOTH_SHADING\n");
g_smooth_fill_texture2d_program = linkProgram(
version,
"#define USE_COLOR_MATERIAL\n"
+ "#define USE_LIGHTING\n"
"#define USE_TEXTURE_2D\n"
"#define SMOOTH_SHADING\n");
+
+ g_flat_fill_solid_shadeless_program = linkProgram(
+ version,
+ "#define USE_COLOR_MATERIAL\n"
+ "#define FLAT_SHADING\n");
+ g_flat_fill_texture2d_shadeless_program = linkProgram(
+ version,
+ "#define USE_COLOR_MATERIAL\n"
+ "#define USE_TEXTURE_2D\n"
+ "#define FLAT_SHADING\n");
+ g_smooth_fill_solid_shadeless_program = linkProgram(
+ version,
+ "#define USE_COLOR_MATERIAL\n"
+ "#define SMOOTH_SHADING\n");
+ g_smooth_fill_texture2d_shadeless_program = linkProgram(
+ version,
+ "#define USE_COLOR_MATERIAL\n"
+ "#define USE_TEXTURE_2D\n"
+ "#define SMOOTH_SHADING\n");
+
g_wireframe_program = linkProgram(
version,
"#define WIREFRAME\n");
@@ -464,21 +494,24 @@ void openSubdiv_osdGLDisplayDeinit(void)
if (g_lighting_ub != 0) {
glDeleteBuffers(1, &g_lighting_ub);
}
- if (g_flat_fill_solid_program) {
- glDeleteProgram(g_flat_fill_solid_program);
- }
- if (g_flat_fill_texture2d_program) {
- glDeleteProgram(g_flat_fill_texture2d_program);
- }
- if (g_smooth_fill_solid_program) {
- glDeleteProgram(g_flat_fill_solid_program);
- }
- if (g_smooth_fill_texture2d_program) {
- glDeleteProgram(g_smooth_fill_texture2d_program);
- }
- if (g_wireframe_program) {
- glDeleteProgram(g_wireframe_program);
- }
+#define SAFE_DELETE_PROGRAM(program) \
+ do { \
+ if (program) { \
+ glDeleteProgram(program); \
+ } \
+ } while (false)
+
+ SAFE_DELETE_PROGRAM(g_flat_fill_solid_program);
+ SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program);
+ SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program);
+ SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program);
+ SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program);
+ SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program);
+ SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program);
+ SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program);
+ SAFE_DELETE_PROGRAM(g_wireframe_program);
+
+#undef SAFE_DELETE_PROGRAM
}
void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl,
@@ -599,23 +632,32 @@ static GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh,
if (fill_quads) {
int model;
- GLboolean use_texture_2d;
+ GLboolean use_texture_2d, use_lighting;
glGetIntegerv(GL_SHADE_MODEL, &model);
glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
+ glGetBooleanv(GL_LIGHTING, &use_lighting);
if (model == GL_FLAT) {
if (use_texture_2d) {
- program = g_flat_fill_texture2d_program;
+ program = use_lighting
+ ? g_flat_fill_texture2d_program
+ : g_flat_fill_texture2d_shadeless_program;
}
else {
- program = g_flat_fill_solid_program;
+ program = use_lighting
+ ? g_flat_fill_solid_program
+ : g_flat_fill_solid_shadeless_program;
}
}
else {
if (use_texture_2d) {
- program = g_smooth_fill_texture2d_program;
+ program = use_lighting
+ ? g_smooth_fill_texture2d_program
+ : g_smooth_fill_texture2d_shadeless_program;
}
else {
- program = g_smooth_fill_solid_program;
+ program = use_lighting
+ ? g_smooth_fill_solid_program
+ : g_smooth_fill_solid_shadeless_program;
}
}
}
diff --git a/release/bin/blender-thumbnailer.py b/release/bin/blender-thumbnailer.py
index fe5d462bba9..5d2dd958a92 100755
--- a/release/bin/blender-thumbnailer.py
+++ b/release/bin/blender-thumbnailer.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
diff --git a/release/datafiles/ctodata.py b/release/datafiles/ctodata.py
index 079f6c3b918..8c1d4a4fb34 100755
--- a/release/datafiles/ctodata.py
+++ b/release/datafiles/ctodata.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ***** BEGIN GPL LICENSE BLOCK *****
diff --git a/release/scripts/modules/blend_render_info.py b/release/scripts/modules/blend_render_info.py
index a62eaeea143..5e4ee0ee4b1 100755
--- a/release/scripts/modules/blend_render_info.py
+++ b/release/scripts/modules/blend_render_info.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# ##### BEGIN GPL LICENSE BLOCK #####
#
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 3af0177c25b..09b4881aac8 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -86,6 +86,7 @@ bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, s
bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test);
void id_sort_by_name(struct ListBase *lb, struct ID *id);
void BKE_id_expand_local(struct ID *id);
+void BKE_id_copy_ensure_local(struct Main *bmain, struct ID *old_id, struct ID *new_id);
bool new_id(struct ListBase *lb, struct ID *id, const char *name);
void id_clear_lib_data(struct Main *bmain, struct ID *id);
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 8f82610a8bb..470098f8c7c 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -156,10 +156,7 @@ bAction *BKE_action_copy(Main *bmain, bAction *src)
}
}
- if (ID_IS_LINKED_DATABLOCK(src)) {
- BKE_id_expand_local(&dst->id);
- BKE_id_lib_local_paths(bmain, src->id.lib, &dst->id);
- }
+ BKE_id_copy_ensure_local(bmain, &src->id, &dst->id);
return dst;
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 790272c4411..c644fe09364 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -194,10 +194,7 @@ bArmature *BKE_armature_copy(Main *bmain, bArmature *arm)
newArm->act_edbone = NULL;
newArm->sketch = NULL;
- if (ID_IS_LINKED_DATABLOCK(arm)) {
- BKE_id_expand_local(&newArm->id);
- BKE_id_lib_local_paths(bmain, arm->id.lib, &newArm->id);
- }
+ BKE_id_copy_ensure_local(bmain, &arm->id, &newArm->id);
return newArm;
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 9027287a457..8ef1fae1155 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -197,10 +197,7 @@ Brush *BKE_brush_copy(Main *bmain, Brush *brush)
/* enable fake user by default */
id_fake_user_set(&brush->id);
- if (ID_IS_LINKED_DATABLOCK(brush)) {
- BKE_id_expand_local(&brushn->id);
- BKE_id_lib_local_paths(bmain, brush->id.lib, &brushn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &brush->id, &brushn->id);
return brushn;
}
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 4229b2a727e..85ce399b770 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -99,10 +99,7 @@ Camera *BKE_camera_copy(Main *bmain, Camera *cam)
camn = BKE_libblock_copy(bmain, &cam->id);
- if (ID_IS_LINKED_DATABLOCK(cam)) {
- BKE_id_expand_local(&camn->id);
- BKE_id_lib_local_paths(bmain, cam->id.lib, &camn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &cam->id, &camn->id);
return camn;
}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 07f4e4f1610..90a514781d7 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -207,10 +207,7 @@ Curve *BKE_curve_copy(Main *bmain, Curve *cu)
id_us_plus((ID *)cun->vfonti);
id_us_plus((ID *)cun->vfontbi);
- if (ID_IS_LINKED_DATABLOCK(cu)) {
- BKE_id_expand_local(&cun->id);
- BKE_id_lib_local_paths(bmain, cu->id.lib, &cun->id);
- }
+ BKE_id_copy_ensure_local(bmain, &cu->id, &cun->id);
return cun;
}
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index aae1ba241e7..708472fa4a5 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -96,10 +96,7 @@ Group *BKE_group_copy(Main *bmain, Group *group)
/* Do not copy group's preview (same behavior as for objects). */
groupn->preview = NULL;
- if (ID_IS_LINKED_DATABLOCK(group)) {
- BKE_id_expand_local(&groupn->id);
- BKE_id_lib_local_paths(bmain, group->id.lib, &groupn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &group->id, &groupn->id);
return groupn;
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 017eb41cd49..ea28dabb945 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -462,10 +462,7 @@ Image *BKE_image_copy(Main *bmain, Image *ima)
BKE_previewimg_id_copy(&nima->id, &ima->id);
- if (ID_IS_LINKED_DATABLOCK(ima)) {
- BKE_id_expand_local(&nima->id);
- BKE_id_lib_local_paths(bmain, ima->id.lib, &nima->id);
- }
+ BKE_id_copy_ensure_local(bmain, &ima->id, &nima->id);
return nima;
}
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index a524f927cad..6cdeaf5e59b 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -170,10 +170,7 @@ Key *BKE_key_copy(Main *bmain, Key *key)
kb = kb->next;
}
- if (ID_IS_LINKED_DATABLOCK(key)) {
- BKE_id_expand_local(&keyn->id);
- BKE_id_lib_local_paths(bmain, key->id.lib, &keyn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &key->id, &keyn->id);
return keyn;
}
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 35fcf211b05..e9d039ad480 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -138,10 +138,7 @@ Lamp *BKE_lamp_copy(Main *bmain, Lamp *la)
BKE_previewimg_id_copy(&lan->id, &la->id);
- if (ID_IS_LINKED_DATABLOCK(la)) {
- BKE_id_expand_local(&lan->id);
- BKE_id_lib_local_paths(bmain, la->id.lib, &lan->id);
- }
+ BKE_id_copy_ensure_local(bmain, &la->id, &lan->id);
return lan;
}
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 82b179d4f1c..b0671f33094 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -297,10 +297,7 @@ Lattice *BKE_lattice_copy(Main *bmain, Lattice *lt)
ltn->editlatt = NULL;
- if (ID_IS_LINKED_DATABLOCK(lt)) {
- BKE_id_expand_local(&ltn->id);
- BKE_id_lib_local_paths(bmain, lt->id.lib, &ltn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &lt->id, &ltn->id);
return ltn;
}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 6718f1a13ce..558c3bb0326 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -271,6 +271,17 @@ void BKE_id_expand_local(ID *id)
}
/**
+ * Ensure new (copied) ID is fully made local.
+ */
+void BKE_id_copy_ensure_local(Main *bmain, ID *old_id, ID *new_id)
+{
+ if (ID_IS_LINKED_DATABLOCK(old_id)) {
+ BKE_id_expand_local(new_id);
+ BKE_id_lib_local_paths(bmain, old_id->lib, new_id);
+ }
+}
+
+/**
* Generic 'make local' function, works for most of datablock types...
*/
void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 2ccdcbba86f..17c90286a5b 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -944,6 +944,10 @@ static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked)
}
for (; id_curr && !is_defined; id_curr = id_curr->next) {
+ if (id_curr == id) {
+ /* We are not interested in self-usages (mostly from drivers or bone constraints...). */
+ continue;
+ }
iter.curr_id = id_curr;
BKE_library_foreach_ID_link(
id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_NOP);
@@ -992,6 +996,10 @@ void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, boo
}
for (; id_curr && !is_defined; id_curr = id_curr->next) {
+ if (id_curr == id) {
+ /* We are not interested in self-usages (mostly from drivers or bone constraints...). */
+ continue;
+ }
iter.curr_id = id_curr;
BKE_library_foreach_ID_link(id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_NOP);
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 1aff5d502f8..430935a5fad 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -218,10 +218,7 @@ FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *l
for (m = (LineStyleModifier *)linestyle->geometry_modifiers.first; m; m = m->next)
BKE_linestyle_geometry_modifier_copy(new_linestyle, m);
- if (ID_IS_LINKED_DATABLOCK(linestyle)) {
- BKE_id_expand_local(&new_linestyle->id);
- BKE_id_lib_local_paths(bmain, linestyle->id.lib, &new_linestyle->id);
- }
+ BKE_id_copy_ensure_local(bmain, &linestyle->id, &new_linestyle->id);
return new_linestyle;
}
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 014461e0d22..21023d9f53c 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -853,10 +853,7 @@ Mask *BKE_mask_copy(Main *bmain, Mask *mask)
/* enable fake user by default */
id_fake_user_set(&mask->id);
- if (ID_IS_LINKED_DATABLOCK(mask)) {
- BKE_id_expand_local(&mask_new->id);
- BKE_id_lib_local_paths(bmain, mask->id.lib, &mask_new->id);
- }
+ BKE_id_copy_ensure_local(bmain, &mask->id, &mask_new->id);
return mask_new;
}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 62aba1af694..0be32c9b84c 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -247,10 +247,7 @@ Material *BKE_material_copy(Main *bmain, Material *ma)
BLI_listbase_clear(&man->gpumaterial);
- if (ID_IS_LINKED_DATABLOCK(ma)) {
- BKE_id_expand_local(&man->id);
- BKE_id_lib_local_paths(bmain, ma->id.lib, &man->id);
- }
+ BKE_id_copy_ensure_local(bmain, &ma->id, &man->id);
return man;
}
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 7e363e5600f..8d024ea9aa5 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -119,10 +119,7 @@ MetaBall *BKE_mball_copy(Main *bmain, MetaBall *mb)
mbn->editelems = NULL;
mbn->lastelem = NULL;
- if (ID_IS_LINKED_DATABLOCK(mb)) {
- BKE_id_expand_local(&mbn->id);
- BKE_id_lib_local_paths(bmain, mb->id.lib, &mbn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &mb->id, &mbn->id);
return mbn;
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 2b35cdc9d64..733e9030056 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -531,10 +531,7 @@ Mesh *BKE_mesh_copy(Main *bmain, Mesh *me)
men->key->from = (ID *)men;
}
- if (ID_IS_LINKED_DATABLOCK(me)) {
- BKE_id_expand_local(&men->id);
- BKE_id_lib_local_paths(bmain, me->id.lib, &men->id);
- }
+ BKE_id_copy_ensure_local(bmain, &me->id, &men->id);
return men;
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 8bae0484920..2b88ae4823c 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1290,10 +1290,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool ski
/* node tree will generate its own interface type */
newtree->interface_type = NULL;
- if (ID_IS_LINKED_DATABLOCK(ntree)) {
- BKE_id_expand_local(&newtree->id);
- BKE_id_lib_local_paths(bmain, ntree->id.lib, &newtree->id);
- }
+ BKE_id_copy_ensure_local(bmain, &ntree->id, &newtree->id);
return newtree;
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 980877fd541..87e55a7ac95 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1006,10 +1006,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
/* Copy runtime surve data. */
obn->curve_cache = NULL;
- if (ID_IS_LINKED_DATABLOCK(ob)) {
- BKE_id_expand_local(&obn->id);
- BKE_id_lib_local_paths(bmain, ob->id.lib, &obn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &ob->id, &obn->id);
/* Do not copy object's preview (mostly due to the fact renderers create temp copy of objects). */
obn->preview = NULL;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 4996f98379e..8e7b66ef183 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -2480,8 +2480,7 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *
// create shadows before writing cache so they get stored
smoke_calc_transparency(sds, scene);
- if (sds->wt)
- {
+ if (sds->wt && sds->total_cells > 1) {
smoke_turbulence_step(sds->wt, sds->fluid);
}
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index 80ee6d50d7e..ee6886e3fb2 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -77,10 +77,7 @@ Speaker *BKE_speaker_copy(Main *bmain, Speaker *spk)
if (spkn->sound)
id_us_plus(&spkn->sound->id);
- if (ID_IS_LINKED_DATABLOCK(spk)) {
- BKE_id_expand_local(&spkn->id);
- BKE_id_lib_local_paths(G.main, spk->id.lib, &spkn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &spk->id, &spkn->id);
return spkn;
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 10a0a39fcdd..e876bf43809 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2699,6 +2699,7 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
num_draw_patches);
}
}
+ glShadeModel(GL_SMOOTH);
return;
}
#endif
@@ -2805,6 +2806,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
num_draw_patches);
}
}
+ glShadeModel(GL_SMOOTH);
return;
}
#endif
@@ -3214,6 +3216,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
setMaterial(userData, new_matnr, &gattribs);
ccgSubSurf_drawGLMesh(ss, true, -1, -1);
+ glShadeModel(GL_SMOOTH);
return;
}
#endif
@@ -3424,15 +3427,18 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
int current_patch = 0;
int mat_nr = -1;
int start_draw_patch = 0, num_draw_patches = 0;
+ bool draw_smooth = false;
for (i = 0; i < num_base_faces; ++i) {
const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i);
const int num_patches = (num_face_verts == 4) ? face_patches
: num_face_verts * grid_patches;
if (faceFlags) {
- mat_nr = faceFlags[i].mat_nr + 1;
+ mat_nr = faceFlags[i].mat_nr;
+ draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
}
else {
mat_nr = 0;
+ draw_smooth = false;
}
if (drawParams != NULL) {
@@ -3447,8 +3453,13 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == num_base_faces - 1);
+ const int next_face = min_ii(i + 1, num_base_faces - 1);
if (!flush && compareDrawOptions) {
- flush |= compareDrawOptions(userData, i, min_ii(i + 1, num_base_faces - 1)) == 0;
+ flush |= compareDrawOptions(userData, i, next_face) == 0;
+ }
+ if (!flush && faceFlags) {
+ bool new_draw_smooth = (faceFlags[next_face].flag & ME_SMOOTH);
+ flush |= (new_draw_smooth != draw_smooth);
}
current_patch += num_patches;
@@ -3458,6 +3469,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
num_draw_patches += num_patches;
}
if (num_draw_patches != 0) {
+ glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
ccgSubSurf_drawGLMesh(ss,
true,
start_draw_patch,
@@ -3470,6 +3482,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
num_draw_patches += num_patches;
}
}
+ glShadeModel(GL_SMOOTH);
return;
}
#endif
@@ -3669,6 +3682,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
ccgSubSurf_drawGLMesh(ss, true, -1, -1);
}
+ glShadeModel(GL_SMOOTH);
return;
}
#endif
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 82c3132d73e..1636042f479 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -491,10 +491,7 @@ Text *BKE_text_copy(Main *bmain, Text *ta)
init_undo_text(tan);
- if (ID_IS_LINKED_DATABLOCK(ta)) {
- BKE_id_expand_local(&tan->id);
- BKE_id_lib_local_paths(bmain, ta->id.lib, &tan->id);
- }
+ BKE_id_copy_ensure_local(bmain, &ta->id, &tan->id);
return tan;
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index d2e0d9d9c83..e98b6b60331 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -872,10 +872,7 @@ Tex *BKE_texture_copy(Main *bmain, Tex *tex)
BKE_previewimg_id_copy(&texn->id, &tex->id);
- if (ID_IS_LINKED_DATABLOCK(tex)) {
- BKE_id_expand_local(&texn->id);
- BKE_id_lib_local_paths(bmain, tex->id.lib, &texn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &tex->id, &texn->id);
return texn;
}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 78342e9919a..de1e3187a70 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -142,10 +142,7 @@ World *BKE_world_copy(Main *bmain, World *wrld)
BLI_listbase_clear(&wrldn->gpumaterial);
- if (ID_IS_LINKED_DATABLOCK(wrld)) {
- BKE_id_expand_local(&wrldn->id);
- BKE_id_lib_local_paths(bmain, wrld->id.lib, &wrldn->id);
- }
+ BKE_id_copy_ensure_local(bmain, &wrld->id, &wrldn->id);
return wrldn;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6c28b8e4f89..80597b844d9 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -7084,6 +7084,7 @@ static void lib_link_movieclip(FileData *fd, Main *main)
for (object = tracking->objects.first; object; object = object->next) {
lib_link_movieTracks(fd, clip, &object->tracks);
+ lib_link_moviePlaneTracks(fd, clip, &object->plane_tracks);
}
clip->id.tag &= ~LIB_TAG_NEED_LINK;
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index d1de83ec8a9..945a4785b9c 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -168,7 +168,7 @@ void DEG_evaluate_on_framechange(struct EvaluationContext *eval_ctx,
struct Main *bmain,
Depsgraph *graph,
float ctime,
- const int layer);
+ const unsigned int layer);
/* Data changed recalculation entry point.
* < context_type: context to perform evaluation for
@@ -176,7 +176,7 @@ void DEG_evaluate_on_framechange(struct EvaluationContext *eval_ctx,
*/
void DEG_evaluate_on_refresh_ex(struct EvaluationContext *eval_ctx,
Depsgraph *graph,
- const int layers);
+ const unsigned int layers);
/* Data changed recalculation entry point.
* < context_type: context to perform evaluation for
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
index 5ce84ee29db..9088e3bf403 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
@@ -288,7 +288,7 @@ static void deg_debug_graphviz_node_single(const DebugContext &ctx,
if (node->type == DEPSNODE_TYPE_ID_REF) {
IDDepsNode *id_node = (IDDepsNode *)node;
char buf[256];
- BLI_snprintf(buf, sizeof(buf), " (Layers: %d)", id_node->layers);
+ BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers);
name += buf;
}
if (ctx.show_eval_priority && node->tclass == DEPSNODE_CLASS_OPERATION) {
@@ -324,7 +324,7 @@ static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx,
if (node->type == DEPSNODE_TYPE_ID_REF) {
IDDepsNode *id_node = (IDDepsNode *)node;
char buf[256];
- BLI_snprintf(buf, sizeof(buf), " (Layers: %d)", id_node->layers);
+ BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers);
name += buf;
}
deg_debug_fprintf(ctx, "// %s\n", name.c_str());
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index 213bb304d73..08b264f8497 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -191,7 +191,7 @@ struct Depsgraph {
/* Layers Visibility .................. */
/* Visible layers bitfield, used for skipping invisible objects updates. */
- int layers;
+ unsigned int layers;
// XXX: additional stuff like eval contexts, mempools for allocating nodes from, etc.
};
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc
index f8d40d0e6a8..a0435c318f0 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cc
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cc
@@ -133,7 +133,7 @@ void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx,
Main *bmain,
Depsgraph *graph,
float ctime,
- const int layers)
+ const unsigned int layers)
{
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
/* Update time on primary timesource. */
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index 3024d625846..c3fd202d832 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -72,13 +72,13 @@ namespace DEG {
static void schedule_children(TaskPool *pool,
Depsgraph *graph,
OperationDepsNode *node,
- const int layers,
+ const unsigned int layers,
const int thread_id);
struct DepsgraphEvalState {
EvaluationContext *eval_ctx;
Depsgraph *graph;
- int layers;
+ unsigned int layers;
};
static void deg_task_run_func(TaskPool *pool,
@@ -140,7 +140,7 @@ static void deg_task_run_func(TaskPool *pool,
OperationDepsNode *child = (OperationDepsNode *)rel->to;
BLI_assert(child->type == DEPSNODE_TYPE_OPERATION);
if (!child->scheduled) {
- int id_layers = child->owner->owner->layers;
+ unsigned int id_layers = child->owner->owner->layers;
if (!((child->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0 &&
(id_layers & state->layers) != 0))
{
@@ -197,14 +197,14 @@ static void deg_task_run_func(TaskPool *pool,
typedef struct CalculatePengindData {
Depsgraph *graph;
- int layers;
+ unsigned int layers;
} CalculatePengindData;
static void calculate_pending_func(void *data_v, int i)
{
CalculatePengindData *data = (CalculatePengindData *)data_v;
Depsgraph *graph = data->graph;
- int layers = data->layers;
+ unsigned int layers = data->layers;
OperationDepsNode *node = graph->operations[i];
IDDepsNode *id_node = node->owner->owner;
@@ -231,7 +231,7 @@ static void calculate_pending_func(void *data_v, int i)
}
}
-static void calculate_pending_parents(Depsgraph *graph, int layers)
+static void calculate_pending_parents(Depsgraph *graph, unsigned int layers)
{
const int num_operations = graph->operations.size();
const bool do_threads = num_operations > 256;
@@ -276,11 +276,11 @@ static void calculate_eval_priority(OperationDepsNode *node)
* dec_parents: Decrement pending parents count, true when child nodes are
* scheduled after a task has been completed.
*/
-static void schedule_node(TaskPool *pool, Depsgraph *graph, int layers,
+static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
OperationDepsNode *node, bool dec_parents,
const int thread_id)
{
- int id_layers = node->owner->owner->layers;
+ unsigned int id_layers = node->owner->owner->layers;
if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0 &&
(id_layers & layers) != 0)
@@ -314,7 +314,7 @@ static void schedule_node(TaskPool *pool, Depsgraph *graph, int layers,
static void schedule_graph(TaskPool *pool,
Depsgraph *graph,
- const int layers)
+ const unsigned int layers)
{
foreach (OperationDepsNode *node, graph->operations) {
schedule_node(pool, graph, layers, node, false, 0);
@@ -324,7 +324,7 @@ static void schedule_graph(TaskPool *pool,
static void schedule_children(TaskPool *pool,
Depsgraph *graph,
OperationDepsNode *node,
- const int layers,
+ const unsigned int layers,
const int thread_id)
{
foreach (DepsRelation *rel, node->outlinks) {
@@ -352,7 +352,7 @@ static void schedule_children(TaskPool *pool,
*/
void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
Depsgraph *graph,
- const int layers)
+ const unsigned int layers)
{
/* Generate base evaluation context, upon which all the others are derived. */
// TODO: this needs both main and scene access...
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.h b/source/blender/depsgraph/intern/eval/deg_eval.h
index 92f87b03803..49c0379939e 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval.h
@@ -47,6 +47,6 @@ struct Depsgraph;
*/
void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
Depsgraph *graph,
- const int layers);
+ const unsigned int layers);
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc
index db807d22b89..eb408f293de 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node.cc
@@ -182,7 +182,7 @@ void IDDepsNode::init(const ID *id, const string &UNUSED(subdata))
this->eval_flags = 0;
/* For object we initialize layers to layer from base. */
- if (GS(id) == ID_OB) {
+ if (GS(id->name) == ID_OB) {
this->layers = 0;
}
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h
index 416996052c9..b2262c4bd12 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node.h
@@ -176,7 +176,7 @@ struct IDDepsNode : public DepsNode {
GHash *components;
/* Layers of this node with accumulated layers of it's output relations. */
- int layers;
+ unsigned int layers;
/* Additional flags needed for scene evaluation.
* TODO(sergey): Only needed for until really granular updates
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
index 6ac45c99798..5832c458896 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
@@ -120,7 +120,7 @@ string ComponentDepsNode::identifier() const
sprintf(typebuf, "(%d)", type);
char layers[16];
- sprintf(layers, "%d", this->layers);
+ sprintf(layers, "%u", this->layers);
return string(typebuf) + name + " : " + idname + " (Layers: " + layers + ")";
}
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h
index 6f62d91cd79..acccb1cdcd4 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_component.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h
@@ -159,7 +159,7 @@ struct ComponentDepsNode : public DepsNode {
// XXX: a poll() callback to check if component's first node can be started?
/* Temporary bitmask, used during graph construction. */
- int layers;
+ unsigned int layers;
};
/* ---------------------------------------- */
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 4d0a2fa53cd..2d8fc76ee7e 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -64,8 +64,8 @@
#endif
/* Distance between input samples */
-#define STROKE_SAMPLE_DIST_MIN_PX 3
-#define STROKE_SAMPLE_DIST_MAX_PX 6
+#define STROKE_SAMPLE_DIST_MIN_PX 1
+#define STROKE_SAMPLE_DIST_MAX_PX 3
/* Distance between start/end points to consider cyclic */
#define STROKE_CYCLIC_DIST_PX 8
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index a623f5cfb9c..f77e795adca 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -382,7 +382,11 @@ typedef bool (*uiMenuStepFunc)(struct bContext *C, int direction, void *arg1);
typedef struct uiPopupMenu uiPopupMenu;
-struct uiPopupMenu *UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL();
+uiPopupMenu *UI_popup_menu_begin(
+ struct bContext *C, const char *title, int icon) ATTR_NONNULL();
+uiPopupMenu *UI_popup_menu_begin_ex(
+ struct bContext *C, const char *title, const char *block_name,
+ int icon) ATTR_NONNULL();
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *head);
struct uiLayout *UI_popup_menu_layout(uiPopupMenu *head);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 11703208b2a..79831cefde6 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -10156,6 +10156,10 @@ static void ui_popup_handler_remove(bContext *C, void *userdata)
{
uiPopupBlockHandle *menu = userdata;
+ if (menu->cancel_func) {
+ menu->cancel_func(C, menu->popup_arg);
+ }
+
/* free menu block if window is closed for some reason */
ui_popup_block_free(C, menu);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index f02aad1ff87..8336efa381b 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -548,6 +548,8 @@ struct uiPopupBlockHandle {
/* store data for refreshing popups */
struct uiPopupBlockCreate popup_create_vars;
+ /* true if we can re-create the popup using 'popup_create_vars' */
+ bool can_refresh;
struct wmTimer *scrolltimer;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 2caf52cf8dc..c621fcf493d 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1701,7 +1701,9 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
ar->do_draw &= ~RGN_DRAW_REFRESH_UI;
for (block = ar->uiblocks.first; block; block = block_next) {
block_next = block->next;
- ui_popup_block_refresh((bContext *)C, block->handle, NULL, NULL);
+ if (block->handle->can_refresh) {
+ ui_popup_block_refresh((bContext *)C, block->handle, NULL, NULL);
+ }
}
}
@@ -1811,6 +1813,8 @@ uiBlock *ui_popup_block_refresh(
bContext *C, uiPopupBlockHandle *handle,
ARegion *butregion, uiBut *but)
{
+ BLI_assert(handle->can_refresh == true);
+
const int margin = UI_POPUP_MARGIN;
wmWindow *window = CTX_wm_window(C);
ARegion *ar = handle->region;
@@ -2001,6 +2005,8 @@ uiPopupBlockHandle *ui_popup_block_create(
handle->popup_create_vars.arg = arg;
handle->popup_create_vars.butregion = but ? butregion : NULL;
copy_v2_v2_int(handle->popup_create_vars.event_xy, &window->eventstate->x);
+ /* caller may free vars used to create this popup, in that case this variable should be disabled. */
+ handle->can_refresh = true;
/* create area region */
ar = ui_region_temp_add(CTX_wm_screen(C));
@@ -2800,6 +2806,7 @@ uiPopupBlockHandle *ui_popup_menu_create(
WM_event_add_mousemove(C);
}
+ handle->can_refresh = false;
MEM_freeN(pup);
return handle;
@@ -2807,14 +2814,17 @@ uiPopupBlockHandle *ui_popup_menu_create(
/******************** Popup Menu API with begin and end ***********************/
-/* only return handler, and set optional title */
-uiPopupMenu *UI_popup_menu_begin(bContext *C, const char *title, int icon)
+/**
+ * Only return handler, and set optional title.
+ * \param block_name: Assigned to uiBlock.name (useful info for debugging).
+ */
+uiPopupMenu *UI_popup_menu_begin_ex(bContext *C, const char *title, const char *block_name, int icon)
{
uiStyle *style = UI_style_get_dpi();
uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
uiBut *but;
- pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN);
+ pup->block = UI_block_begin(C, NULL, block_name, UI_EMBOSS_PULLDOWN);
pup->block->flag |= UI_BLOCK_POPUP_MEMORY | UI_BLOCK_IS_FLIP;
pup->block->puphash = ui_popup_menu_hash(title);
pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style);
@@ -2845,6 +2855,11 @@ uiPopupMenu *UI_popup_menu_begin(bContext *C, const char *title, int icon)
return pup;
}
+uiPopupMenu *UI_popup_menu_begin(bContext *C, const char *title, int icon)
+{
+ return UI_popup_menu_begin_ex(C, title, __func__, icon);
+}
+
/* set the whole structure to work */
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
{
@@ -2860,7 +2875,8 @@ void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
WM_event_add_mousemove(C);
-
+
+ menu->can_refresh = false;
MEM_freeN(pup);
}
@@ -2991,6 +3007,7 @@ void UI_pie_menu_end(bContext *C, uiPieMenu *pie)
menu, WM_HANDLER_ACCEPT_DBL_CLICK);
WM_event_add_mousemove(C);
+ menu->can_refresh = false;
MEM_freeN(pie);
}
@@ -3203,7 +3220,8 @@ void UI_popup_menu_reports(bContext *C, ReportList *reports)
if (pup == NULL) {
char title[UI_MAX_DRAW_STR];
BLI_snprintf(title, sizeof(title), "%s: %s", IFACE_("Report"), report->typestr);
- pup = UI_popup_menu_begin(C, title, ICON_NONE);
+ /* popup_menu stuff does just what we need (but pass meaningful block name) */
+ pup = UI_popup_menu_begin_ex(C, title, __func__, ICON_NONE);
layout = UI_popup_menu_layout(pup);
}
else {
@@ -3332,7 +3350,7 @@ void UI_popup_block_close(bContext *C, wmWindow *win, uiBlock *block)
UI_popup_handlers_remove(&win->modalhandlers, block->handle);
ui_popup_block_free(C, block->handle);
- /* In the case we have nested popups, closing one may need to redraw anorher, see: T48874 */
+ /* In the case we have nested popups, closing one may need to redraw another, see: T48874 */
for (ARegion *ar = win->screen->regionbase.first; ar; ar = ar->next) {
ED_region_tag_refresh_ui(ar);
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 76d0143e898..b2aefb5e523 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -1210,7 +1210,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
/* setup job */
WM_jobs_customdata_set(wm_job, ip, icon_preview_free);
- WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL);
+ WM_jobs_timer(wm_job, 0.1, NC_WINDOW , NC_WINDOW);
WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob);
WM_jobs_start(CTX_wm_manager(C), wm_job);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 415839ab761..396d71f0a20 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -818,7 +818,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
- kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", ACTIONMOUSE, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", LEFTMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", true); /* toggle */
WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_view_all", HOMEKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index cf6e2ac226e..26eeaa91dd0 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -794,22 +794,37 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
link->tosock = node_group_find_input_socket(gnode, iosock->identifier);
}
else if (fromselect) {
- bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link->fromnode, link->fromsock);
- bNodeSocket *output_sock;
-
- /* update the group node and interface node sockets,
- * so the new interface socket can be linked.
- */
- node_group_verify(ntree, gnode, (ID *)ngroup);
- node_group_output_verify(ngroup, output_node, (ID *)ngroup);
+ /* First check whether the source of this link is already connected to an output.
+ * If yes, reuse that output instead of duplicating it. */
+ bool connected = false;
+ bNodeLink *olink;
+ for (olink = ngroup->links.first; olink; olink = olink->next) {
+ if (olink->fromsock == link->fromsock && olink->tonode == output_node) {
+ bNodeSocket *output_sock = node_group_find_output_socket(gnode, olink->tosock->identifier);
+ link->fromnode = gnode;
+ link->fromsock = output_sock;
+ connected = true;
+ }
+ }
- /* create new internal link */
- output_sock = node_group_output_find_socket(output_node, iosock->identifier);
- nodeAddLink(ngroup, link->fromnode, link->fromsock, output_node, output_sock);
-
- /* redirect external link */
- link->fromnode = gnode;
- link->fromsock = node_group_find_output_socket(gnode, iosock->identifier);
+ if (!connected) {
+ bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link->fromnode, link->fromsock);
+ bNodeSocket *output_sock;
+
+ /* update the group node and interface node sockets,
+ * so the new interface socket can be linked.
+ */
+ node_group_verify(ntree, gnode, (ID *)ngroup);
+ node_group_output_verify(ngroup, output_node, (ID *)ngroup);
+
+ /* create new internal link */
+ output_sock = node_group_output_find_socket(output_node, iosock->identifier);
+ nodeAddLink(ngroup, link->fromnode, link->fromsock, output_node, output_sock);
+
+ /* redirect external link */
+ link->fromnode = gnode;
+ link->fromsock = node_group_find_output_socket(gnode, iosock->identifier);
+ }
}
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 2ec5b5f3c08..da7f707e599 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -1413,7 +1413,9 @@ static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_i
if ((ID *)v3d->camera == old_id) {
v3d->camera = (Object *)new_id;
if (!new_id) {
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ /* 3D view might be inactive, in that case needs to use slink->regionbase */
+ ListBase *regionbase = (slink == sa->spacedata.first) ? &sa->regionbase : &slink->regionbase;
+ for (ar = regionbase->first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = is_local ? ((RegionView3D *)ar->regiondata)->localvd : ar->regiondata;
if (rv3d && (rv3d->persp == RV3D_CAMOB)) {
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index a69b64a25d7..14d4e8cbe68 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -1724,3 +1724,9 @@ void GPU_pass_free(GPUPass *pass)
MEM_freeN(pass->vertexcode);
MEM_freeN(pass);
}
+
+void GPU_pass_free_nodes(ListBase *nodes)
+{
+ gpu_nodes_free(nodes);
+}
+
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 417e46a83ee..7af17f9122d 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -183,6 +183,7 @@ void GPU_pass_update_uniforms(GPUPass *pass);
void GPU_pass_unbind(GPUPass *pass);
void GPU_pass_free(GPUPass *pass);
+void GPU_pass_free_nodes(ListBase *nodes);
void gpu_codegen_init(void);
void gpu_codegen_exit(void);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 00af1991eaf..60df9e87cc0 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -257,6 +257,9 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam
material->cameratexcofacloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_CAMERA_TEXCO_FACTORS));
return 1;
}
+ else {
+ GPU_pass_free_nodes(&material->nodes);
+ }
return 0;
}
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index fbeabb351ac..e208ef39719 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -218,11 +218,18 @@ typedef struct ScrArea {
char temp, pad;
struct SpaceType *type; /* callbacks for this space type */
-
- ListBase spacedata; /* SpaceLink */
- ListBase regionbase; /* ARegion */
- ListBase handlers; /* wmEventHandler */
-
+
+ /* A list of space links (editors) that were open in this area before. When
+ * changing the editor type, we try to reuse old editor data from this list.
+ * The first item is the active/visible one.
+ */
+ ListBase spacedata; /* SpaceLink */
+ /* NOTE: This region list is the one from the active/visible editor (first item in
+ * spacedata list). Use SpaceLink.regionbase if it's inactive (but only then)!
+ */
+ ListBase regionbase; /* ARegion */
+ ListBase handlers; /* wmEventHandler */
+
ListBase actionzones; /* AZone */
} ScrArea;
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index df114b0cc03..44ed05e5880 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -64,10 +64,10 @@ EnumPropertyItem rna_enum_id_type_items[] = {
{ID_LT, "LATTICE", ICON_LATTICE_DATA, "Lattice", ""},
{ID_MSK, "MASK", ICON_MOD_MASK, "Mask", ""},
{ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""},
- {ID_MB, "META", ICON_META_DATA, "MetaBall", ""},
+ {ID_MB, "META", ICON_META_DATA, "Metaball", ""},
{ID_ME, "MESH", ICON_MESH_DATA, "Mesh", ""},
- {ID_MC, "MOVIECLIP", ICON_CLIP, "MovieClip", ""},
- {ID_NT, "NODETREE", ICON_NODETREE, "NodeTree", ""},
+ {ID_MC, "MOVIECLIP", ICON_CLIP, "Movie Clip", ""},
+ {ID_NT, "NODETREE", ICON_NODETREE, "Node Tree", ""},
{ID_OB, "OBJECT", ICON_OBJECT_DATA, "Object", ""},
{ID_PC, "PAINTCURVE", ICON_CURVE_BEZCURVE, "Paint Curve", ""},
{ID_PAL, "PALETTE", ICON_COLOR, "Palette", ""},
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index bda9763201a..72ecebdb7df 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2605,6 +2605,10 @@ static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *p
BKE_image_signal(ima, iuser, IMA_SIGNAL_SRC_CHANGE);
rna_Node_update(bmain, scene, ptr);
+
+ if (scene->nodetree != NULL) {
+ ntreeCompositForceHidden(scene->nodetree);
+ }
}
static EnumPropertyItem *renderresult_layers_add_enum(RenderLayer *rl)
@@ -2738,6 +2742,14 @@ static EnumPropertyItem *rna_Node_scene_layer_itemf(bContext *UNUSED(C), Pointer
return item;
}
+static void rna_Node_scene_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ rna_Node_update(bmain, scene, ptr);
+ if (scene->nodetree != NULL) {
+ ntreeCompositForceHidden(scene->nodetree);
+ }
+}
+
static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA *ptr,
PropertyRNA *UNUSED(prop), bool *r_free)
{
@@ -4745,7 +4757,7 @@ static void def_cmp_render_layers(StructRNA *srna)
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Node_scene_layer_itemf");
RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
RNA_def_property_ui_text(prop, "Layer", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_scene_layer_update");
}
static void rna_def_cmp_output_file_slot_file(BlenderRNA *brna)
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 962ed3c040d..3825db14e93 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -862,11 +862,8 @@ static int wm_automatic_draw_method(wmWindow *win)
* copy to texture is slow though and so we use overlap instead there. */
if (win->drawmethod == USER_DRAW_AUTOMATIC) {
- /* ATI opensource driver is known to be very slow at this */
- if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE))
- return USER_DRAW_OVERLAP;
/* Windows software driver darkens color on each redraw */
- else if (GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_WIN, GPU_DRIVER_SOFTWARE))
+ if (GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_WIN, GPU_DRIVER_SOFTWARE))
return USER_DRAW_OVERLAP_FLIP;
else if (GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_UNIX, GPU_DRIVER_SOFTWARE))
return USER_DRAW_OVERLAP;