diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-07-28 05:00:58 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-07-28 05:00:58 +0300 |
commit | 251349c3c2269fff915d1bb85911211563493071 (patch) | |
tree | 35524bdb77d583562227ee11b1ff516ea278e00e | |
parent | b1532493c27b08444745cef348641f3a0e899ba8 (diff) | |
parent | a27acefd0c89aab63a6c243a844e2790dfad961a (diff) |
Merge branch 'master' into blender2.8
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(<n->id); - BKE_id_lib_local_paths(bmain, lt->id.lib, <n->id); - } + BKE_id_copy_ensure_local(bmain, <->id, <n->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; |