diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-01-28 07:18:33 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-01-28 07:18:33 +0300 |
commit | 88174bd22c8798fa5038a3b8d5192e052bfe673e (patch) | |
tree | 728c5654cf0fb879027b774d5b4bf964ffe543ec | |
parent | 7aaede920fd1376fc06edd45c73403f2084a64bc (diff) | |
parent | 3c852ba0741f794a697f95073b04921e9ff94039 (diff) |
Merge branch 'master' into blender2.8
23 files changed, 466 insertions, 381 deletions
diff --git a/build_files/cmake/example_scripts/make_quicky.py b/build_files/cmake/example_scripts/make_quicky.py index 49c284e354d..a1334d6fc83 100755 --- a/build_files/cmake/example_scripts/make_quicky.py +++ b/build_files/cmake/example_scripts/make_quicky.py @@ -107,12 +107,12 @@ def main(): return # execute - cmd = "make %s %s blender/fast" % (" ".join(args), " ".join(targets_new)) + cmd = ["make"] + args + targets_new + ["blender/fast"] print("cmake building with targets: %s" % " ".join(targets_new)) - print("executing: %s" % cmd) + print("executing: %s" % " ".join(cmd)) - import os - os.system(cmd) + import subprocess + subprocess.call(cmd) if __name__ == "__main__": main() diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index 9b0905da030..ad205cc228c 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -28,6 +28,9 @@ Module for accessing project file data for Blender. Before use, call init(cmake_build_dir). """ +# TODO: Use CMAKE_EXPORT_COMPILE_COMMANDS (compile_commands.json) +# Instead of Eclipse project format. + __all__ = ( "SIMPLE_PROJECTFILE", "SOURCE_DIR", @@ -45,14 +48,22 @@ __all__ = ( import sys -if not sys.version.startswith("3"): +if sys.version_info.major < 3: print("\nPython3.x needed, found %s.\nAborting!\n" % sys.version.partition(" ")[0]) sys.exit(1) +import subprocess import os -from os.path import join, dirname, normpath, abspath, splitext, exists +from os.path import ( + abspath, + dirname, + exists, + join, + normpath, + splitext, +) SOURCE_DIR = join(dirname(__file__), "..", "..") SOURCE_DIR = normpath(SOURCE_DIR) @@ -146,13 +157,13 @@ def cmake_advanced_info(): raise Exception("Error: win32 is not supported") else: if make_exe_basename.startswith(("make", "gmake")): - cmd = 'cmake "%s" -G"Eclipse CDT4 - Unix Makefiles"' % CMAKE_DIR + cmd = ("cmake", CMAKE_DIR, "-GEclipse CDT4 - Unix Makefiles") elif make_exe_basename.startswith("ninja"): - cmd = 'cmake "%s" -G"Eclipse CDT4 - Ninja"' % CMAKE_DIR + cmd = ("cmake", CMAKE_DIR, "-GEclipse CDT4 - Ninja") else: raise Exception("Unknown make program %r" % make_exe) - os.system(cmd) + subprocess.check_call(cmd) return join(CMAKE_DIR, ".cproject") includes = [] diff --git a/doc/python_api/examples/bpy.types.Operator.6.py b/doc/python_api/examples/bpy.types.Operator.6.py new file mode 100644 index 00000000000..d32a7d5fd4a --- /dev/null +++ b/doc/python_api/examples/bpy.types.Operator.6.py @@ -0,0 +1,38 @@ +""" +Enum Search Popup ++++++++++++++++++ + +You may want to have an operator prompt the user to select an item +from a search field, this can be done using :class:`bpy.types.Operator.invoke_search_popup`. +""" +import bpy +from bpy.props import EnumProperty + + +class SearchEnumOperator(bpy.types.Operator): + bl_idname = "object.search_enum_operator" + bl_label = "Search Enum Operator" + bl_property = "my_search" + + my_search = EnumProperty( + name="My Search", + items=( + ('FOO', "Foo", ""), + ('BAR', "Bar", ""), + ('BAZ', "Baz", ""), + ), + ) + + def execute(self, context): + self.report({'INFO'}, "Selected:" + self.my_search) + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.invoke_search_popup(self) + return {'RUNNING_MODAL'} + + +bpy.utils.register_class(SearchEnumOperator) + +# test call +bpy.ops.object.search_enum_operator('INVOKE_DEFAULT') diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index a165fc00d74..c0f89fcfbd1 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -1139,12 +1139,19 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, mesh_synced.insert(mesh); /* create derived mesh */ - array<int> oldtriangle = mesh->triangles; + array<int> oldtriangles; + array<Mesh::SubdFace> oldsubd_faces; + array<int> oldsubd_face_corners; + oldtriangles.steal_data(mesh->triangles); + oldsubd_faces.steal_data(mesh->subd_faces); + oldsubd_face_corners.steal_data(mesh->subd_face_corners); /* compares curve_keys rather than strands in order to handle quick hair * adjustments in dynamic BVH - other methods could probably do this better*/ - array<float3> oldcurve_keys = mesh->curve_keys; - array<float> oldcurve_radius = mesh->curve_radius; + array<float3> oldcurve_keys; + array<float> oldcurve_radius; + oldcurve_keys.steal_data(mesh->curve_keys); + oldcurve_radius.steal_data(mesh->curve_radius); mesh->clear(); mesh->used_shaders = used_shaders; @@ -1208,28 +1215,11 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob, sync_mesh_fluid_motion(b_ob, scene, mesh); /* tag update */ - bool rebuild = false; - - if(oldtriangle.size() != mesh->triangles.size()) - rebuild = true; - else if(oldtriangle.size()) { - if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(int)*oldtriangle.size()) != 0) - rebuild = true; - } - - if(oldcurve_keys.size() != mesh->curve_keys.size()) - rebuild = true; - else if(oldcurve_keys.size()) { - if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float3)*oldcurve_keys.size()) != 0) - rebuild = true; - } - - if(oldcurve_radius.size() != mesh->curve_radius.size()) - rebuild = true; - else if(oldcurve_radius.size()) { - if(memcmp(&oldcurve_radius[0], &mesh->curve_radius[0], sizeof(float)*oldcurve_radius.size()) != 0) - rebuild = true; - } + bool rebuild = (oldtriangles != mesh->triangles) || + (oldsubd_faces != mesh->subd_faces) || + (oldsubd_face_corners != mesh->subd_face_corners) || + (oldcurve_keys != mesh->curve_keys) || + (oldcurve_radius != mesh->curve_radius); mesh->tag_update(scene, rebuild); diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index ec10e452148..c8f505e8418 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -22,12 +22,12 @@ CCL_NAMESPACE_BEGIN typedef ccl_addr_space struct Bssrdf { SHADER_CLOSURE_BASE; - float radius; + float3 radius; + float3 albedo; float sharpness; - float d; float texture_blur; - float albedo; float roughness; + float channels; } Bssrdf; /* Planar Truncated Gaussian @@ -200,7 +200,7 @@ ccl_device_inline float bssrdf_burley_fitting(float A) /* Scale mean free path length so it gives similar looking result * to Cubic and Gaussian models. */ -ccl_device_inline float bssrdf_burley_compatible_mfp(float r) +ccl_device_inline float3 bssrdf_burley_compatible_mfp(float3 r) { return 0.25f * M_1_PI_F * r; } @@ -208,13 +208,14 @@ ccl_device_inline float bssrdf_burley_compatible_mfp(float r) ccl_device void bssrdf_burley_setup(Bssrdf *bssrdf) { /* Mean free path length. */ - const float l = bssrdf_burley_compatible_mfp(bssrdf->radius); + const float3 l = bssrdf_burley_compatible_mfp(bssrdf->radius); /* Surface albedo. */ - const float A = bssrdf->albedo; - const float s = bssrdf_burley_fitting(A); - const float d = l / s; + const float3 A = bssrdf->albedo; + const float3 s = make_float3(bssrdf_burley_fitting(A.x), + bssrdf_burley_fitting(A.y), + bssrdf_burley_fitting(A.z)); - bssrdf->d = d; + bssrdf->radius = l / s; } ccl_device float bssrdf_burley_eval(const float d, float r) @@ -343,42 +344,68 @@ ccl_device_inline Bssrdf *bssrdf_alloc(ShaderData *sd, float3 weight) return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? bssrdf : NULL; } -ccl_device int bssrdf_setup(Bssrdf *bssrdf, ClosureType type) +ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type) { - if(bssrdf->radius < BSSRDF_MIN_RADIUS) { - /* revert to diffuse BSDF if radius too small */ - int flag; + int flag = 0; + int bssrdf_channels = 3; + float3 diffuse_weight = make_float3(0.0f, 0.0f, 0.0f); + + /* Verify if the radii are large enough to sample without precision issues. */ + if(bssrdf->radius.x < BSSRDF_MIN_RADIUS) { + diffuse_weight.x = bssrdf->weight.x; + bssrdf->weight.x = 0.0f; + bssrdf->radius.x = 0.0f; + bssrdf_channels--; + } + if(bssrdf->radius.y < BSSRDF_MIN_RADIUS) { + diffuse_weight.y = bssrdf->weight.y; + bssrdf->weight.y = 0.0f; + bssrdf->radius.y = 0.0f; + bssrdf_channels--; + } + if(bssrdf->radius.z < BSSRDF_MIN_RADIUS) { + diffuse_weight.z = bssrdf->weight.z; + bssrdf->weight.z = 0.0f; + bssrdf->radius.z = 0.0f; + bssrdf_channels--; + } + + if(bssrdf_channels < 3) { + /* Add diffuse BSDF if any radius too small. */ #ifdef __PRINCIPLED__ if(type == CLOSURE_BSSRDF_PRINCIPLED_ID) { float roughness = bssrdf->roughness; float3 N = bssrdf->N; - float3 weight = bssrdf->weight; - float sample_weight = bssrdf->sample_weight; - PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bssrdf; + PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diffuse_weight); - bsdf->N = N; - bsdf->roughness = roughness; - bsdf->weight = weight; - bsdf->sample_weight = sample_weight; - flag = bsdf_principled_diffuse_setup(bsdf); - bsdf->type = CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID; + if(bsdf) { + bsdf->type = CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID; + bsdf->N = N; + bsdf->roughness = roughness; + flag |= bsdf_principled_diffuse_setup(bsdf); + } } else #endif /* __PRINCIPLED__ */ { - DiffuseBsdf *bsdf = (DiffuseBsdf*)bssrdf; - bsdf->N = bssrdf->N; - flag = bsdf_diffuse_setup(bsdf); - bsdf->type = CLOSURE_BSDF_BSSRDF_ID; + DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd, sizeof(DiffuseBsdf), diffuse_weight); + + if(bsdf) { + bsdf->type = CLOSURE_BSDF_BSSRDF_ID; + bsdf->N = bssrdf->N; + flag |= bsdf_diffuse_setup(bsdf); + } } - - return flag; } - else { + + /* Setup BSSRDF if radius is large enough. */ + if(bssrdf_channels > 0) { + bssrdf->type = type; + bssrdf->channels = bssrdf_channels; + bssrdf->sample_weight = fabsf(average(bssrdf->weight)) * bssrdf->channels; bssrdf->texture_blur = saturate(bssrdf->texture_blur); bssrdf->sharpness = saturate(bssrdf->sharpness); - bssrdf->type = type; if(type == CLOSURE_BSSRDF_BURLEY_ID || type == CLOSURE_BSSRDF_PRINCIPLED_ID) @@ -386,32 +413,84 @@ ccl_device int bssrdf_setup(Bssrdf *bssrdf, ClosureType type) bssrdf_burley_setup(bssrdf); } - return SD_BSSRDF; + flag |= SD_BSSRDF; } + else { + bssrdf->type = type; + bssrdf->sample_weight = 0.0f; + } + + return flag; } ccl_device void bssrdf_sample(const ShaderClosure *sc, float xi, float *r, float *h) { const Bssrdf *bssrdf = (const Bssrdf*)sc; + float radius; + + /* Sample color channel and reuse random number. Only a subset of channels + * may be used if their radius was too small to handle as BSSRDF. */ + xi *= bssrdf->channels; + + if(xi < 1.0f) { + radius = (bssrdf->radius.x > 0.0f)? bssrdf->radius.x: + (bssrdf->radius.y > 0.0f)? bssrdf->radius.y: + bssrdf->radius.z; + } + else if(xi < 2.0f) { + xi -= 1.0f; + radius = (bssrdf->radius.x > 0.0f)? bssrdf->radius.y: + bssrdf->radius.z; + } + else { + xi -= 2.0f; + radius = bssrdf->radius.z; + } + + /* Sample BSSRDF. */ + if(bssrdf->type == CLOSURE_BSSRDF_CUBIC_ID) { + bssrdf_cubic_sample(radius, bssrdf->sharpness, xi, r, h); + } + else if(bssrdf->type == CLOSURE_BSSRDF_GAUSSIAN_ID){ + bssrdf_gaussian_sample(radius, xi, r, h); + } + else { /*if(bssrdf->type == CLOSURE_BSSRDF_BURLEY_ID || bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/ + bssrdf_burley_sample(radius, xi, r, h); + } +} + +ccl_device float bssrdf_channel_pdf(const Bssrdf *bssrdf, float radius, float r) +{ + if(radius == 0.0f) { + return 0.0f; + } + else if(bssrdf->type == CLOSURE_BSSRDF_CUBIC_ID) { + return bssrdf_cubic_pdf(radius, bssrdf->sharpness, r); + } + else if(bssrdf->type == CLOSURE_BSSRDF_GAUSSIAN_ID) { + return bssrdf_gaussian_pdf(radius, r); + } + else { /*if(bssrdf->type == CLOSURE_BSSRDF_BURLEY_ID || bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/ + return bssrdf_burley_pdf(radius, r); + } +} + +ccl_device_forceinline float3 bssrdf_eval(const ShaderClosure *sc, float r) +{ + const Bssrdf *bssrdf = (const Bssrdf*)sc; - if(sc->type == CLOSURE_BSSRDF_CUBIC_ID) - bssrdf_cubic_sample(bssrdf->radius, bssrdf->sharpness, xi, r, h); - else if(sc->type == CLOSURE_BSSRDF_GAUSSIAN_ID) - bssrdf_gaussian_sample(bssrdf->radius, xi, r, h); - else /*if(sc->type == CLOSURE_BSSRDF_BURLEY_ID || sc->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/ - bssrdf_burley_sample(bssrdf->d, xi, r, h); + return make_float3( + bssrdf_channel_pdf(bssrdf, bssrdf->radius.x, r), + bssrdf_channel_pdf(bssrdf, bssrdf->radius.y, r), + bssrdf_channel_pdf(bssrdf, bssrdf->radius.z, r)); } ccl_device_forceinline float bssrdf_pdf(const ShaderClosure *sc, float r) { const Bssrdf *bssrdf = (const Bssrdf*)sc; + float3 pdf = bssrdf_eval(sc, r); - if(sc->type == CLOSURE_BSSRDF_CUBIC_ID) - return bssrdf_cubic_pdf(bssrdf->radius, bssrdf->sharpness, r); - else if(sc->type == CLOSURE_BSSRDF_GAUSSIAN_ID) - return bssrdf_gaussian_pdf(bssrdf->radius, r); - else /*if(sc->type == CLOSURE_BSSRDF_BURLEY_ID || sc->type == CLOSURE_BSSRDF_PRINCIPLED_ID)*/ - return bssrdf_burley_pdf(bssrdf->d, r); + return (pdf.x + pdf.y + pdf.z) / bssrdf->channels; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index 63fe7822e2a..fe2a7d179a4 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -333,7 +333,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, /* set up random number generator */ uint lcg_state = lcg_state_init(state, 0x68bc21eb); - int num_samples = kernel_data.integrator.subsurface_samples; + int num_samples = kernel_data.integrator.subsurface_samples * 3; float num_samples_inv = 1.0f/num_samples; uint bssrdf_rng_hash = cmj_hash(state->rng_hash, i); diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h index 2ae866bb051..e5e915791cb 100644 --- a/intern/cycles/kernel/kernel_path_state.h +++ b/intern/cycles/kernel/kernel_path_state.h @@ -179,13 +179,13 @@ ccl_device_inline float path_state_continuation_probability(KernelGlobals *kg, #endif } else { - /* Test max bounces for various ray types. */ + /* Test max bounces for various ray types. + The check for max_volume_bounce doesn't happen here but inside volume_shader_sample(). + See T53914. + */ if((state->bounce >= kernel_data.integrator.max_bounce) || (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) || (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) || -#ifdef __VOLUME__ - (state->volume_bounce >= kernel_data.integrator.max_volume_bounce) || -#endif (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce)) { return 0.0f; diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 26d3fcf15b2..5f2f00c5ceb 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -611,6 +611,8 @@ void shader_bsdf_eval(KernelGlobals *kg, ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd, float *randu) { + /* Note the sampling here must match shader_bssrdf_pick, + * since we reuse the same random number. */ int sampled = 0; if(sd->num_closure > 1) { @@ -620,7 +622,7 @@ ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd, for(int i = 0; i < sd->num_closure; i++) { const ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_BSDF(sc->type)) { + if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { sum += sc->sample_weight; } } @@ -631,7 +633,7 @@ ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd, for(int i = 0; i < sd->num_closure; i++) { const ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_BSDF(sc->type)) { + if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { float next_sum = partial_sum + sc->sample_weight; if(r < next_sum) { @@ -648,13 +650,16 @@ ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd, } } - return &sd->closure[sampled]; + const ShaderClosure *sc = &sd->closure[sampled]; + return CLOSURE_IS_BSDF(sc->type)? sc: NULL; } ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd, ccl_addr_space float3 *throughput, float *randu) { + /* Note the sampling here must match shader_bsdf_pick, + * since we reuse the same random number. */ int sampled = 0; if(sd->num_closure > 1) { @@ -703,7 +708,8 @@ ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd, } } - return &sd->closure[sampled]; + const ShaderClosure *sc = &sd->closure[sampled]; + return CLOSURE_IS_BSSRDF(sc->type)? sc: NULL; } ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg, diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h index c79992ee99b..582a20704d3 100644 --- a/intern/cycles/kernel/kernel_subsurface.h +++ b/intern/cycles/kernel/kernel_subsurface.h @@ -23,11 +23,6 @@ CCL_NAMESPACE_BEGIN * */ -/* TODO: - * - test using power heuristic for combing bssrdfs - * - try to reduce one sample model variance - */ - ccl_device_inline float3 subsurface_scatter_eval(ShaderData *sd, const ShaderClosure *sc, float disk_r, @@ -63,12 +58,11 @@ ccl_device_inline float3 subsurface_scatter_eval(ShaderData *sd, float sample_weight = (all)? 1.0f: sc->sample_weight * sample_weight_inv; /* compute pdf */ - float pdf = bssrdf_pdf(sc, r); - float disk_pdf = bssrdf_pdf(sc, disk_r); + float3 eval = bssrdf_eval(sc, r); + float pdf = bssrdf_pdf(sc, disk_r); - /* TODO power heuristic is not working correct here */ - eval_sum += sc->weight*pdf; //*sample_weight*disk_pdf; - pdf_sum += sample_weight*disk_pdf; //*sample_weight*disk_pdf; + eval_sum += sc->weight * eval; + pdf_sum += sample_weight * pdf; } } @@ -190,20 +184,20 @@ ccl_device_inline int subsurface_scatter_multi_intersect( disk_N = sd->Ng; make_orthonormals(disk_N, &disk_T, &disk_B); - if(disk_u < 0.5f) { + if(disk_v < 0.5f) { pick_pdf_N = 0.5f; pick_pdf_T = 0.25f; pick_pdf_B = 0.25f; - disk_u *= 2.0f; + disk_v *= 2.0f; } - else if(disk_u < 0.75f) { + else if(disk_v < 0.75f) { float3 tmp = disk_N; disk_N = disk_T; disk_T = tmp; pick_pdf_N = 0.25f; pick_pdf_T = 0.5f; pick_pdf_B = 0.25f; - disk_u = (disk_u - 0.5f)*4.0f; + disk_v = (disk_v - 0.5f)*4.0f; } else { float3 tmp = disk_N; @@ -212,15 +206,14 @@ ccl_device_inline int subsurface_scatter_multi_intersect( pick_pdf_N = 0.25f; pick_pdf_T = 0.25f; pick_pdf_B = 0.5f; - disk_u = (disk_u - 0.75f)*4.0f; + disk_v = (disk_v - 0.75f)*4.0f; } /* sample point on disk */ - float phi = M_2PI_F * disk_u; - float disk_r = disk_v; - float disk_height; + float phi = M_2PI_F * disk_v; + float disk_height, disk_r; - bssrdf_sample(sc, disk_r, &disk_r, &disk_height); + bssrdf_sample(sc, disk_u, &disk_r, &disk_height); float3 disk_P = (disk_r*cosf(phi)) * disk_T + (disk_r*sinf(phi)) * disk_B; @@ -359,20 +352,20 @@ ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_a disk_N = sd->Ng; make_orthonormals(disk_N, &disk_T, &disk_B); - if(disk_u < 0.5f) { + if(disk_v < 0.5f) { pick_pdf_N = 0.5f; pick_pdf_T = 0.25f; pick_pdf_B = 0.25f; - disk_u *= 2.0f; + disk_v *= 2.0f; } - else if(disk_u < 0.75f) { + else if(disk_v < 0.75f) { float3 tmp = disk_N; disk_N = disk_T; disk_T = tmp; pick_pdf_N = 0.25f; pick_pdf_T = 0.5f; pick_pdf_B = 0.25f; - disk_u = (disk_u - 0.5f)*4.0f; + disk_v = (disk_v - 0.5f)*4.0f; } else { float3 tmp = disk_N; @@ -381,15 +374,14 @@ ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_a pick_pdf_N = 0.25f; pick_pdf_T = 0.25f; pick_pdf_B = 0.5f; - disk_u = (disk_u - 0.75f)*4.0f; + disk_v = (disk_v - 0.75f)*4.0f; } /* sample point on disk */ - float phi = M_2PI_F * disk_u; - float disk_r = disk_v; - float disk_height; + float phi = M_2PI_F * disk_v; + float disk_height, disk_r; - bssrdf_sample(sc, disk_r, &disk_r, &disk_height); + bssrdf_sample(sc, disk_u, &disk_r, &disk_height); float3 disk_P = (disk_r*cosf(phi)) * disk_T + (disk_r*sinf(phi)) * disk_B; diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 27a96720c1e..3e7905f26df 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -51,62 +51,27 @@ using namespace OSL; class CBSSRDFClosure : public CClosurePrimitive { public: Bssrdf params; - float3 radius; - float3 albedo; void alloc(ShaderData *sd, int path_flag, float3 weight, ClosureType type) { - float sample_weight = fabsf(average(weight)); - - /* disable in case of diffuse ancestor, can't see it well then and - * adds considerably noise due to probabilities of continuing path - * getting lower and lower */ - if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { - radius = make_float3(0.0f, 0.0f, 0.0f); - } - - if(sample_weight > CLOSURE_WEIGHT_CUTOFF) { - /* sharpness */ - float sharpness = params.sharpness; - /* texture color blur */ - float texture_blur = params.texture_blur; - - /* create one closure per color channel */ - Bssrdf *bssrdf = bssrdf_alloc(sd, make_float3(weight.x, 0.0f, 0.0f)); - if(bssrdf) { - bssrdf->sample_weight = sample_weight; - bssrdf->radius = radius.x; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.x; - bssrdf->sharpness = sharpness; - bssrdf->N = params.N; - bssrdf->roughness = params.roughness; - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)type); + Bssrdf *bssrdf = bssrdf_alloc(sd, weight); + + if(bssrdf) { + /* disable in case of diffuse ancestor, can't see it well then and + * adds considerably noise due to probabilities of continuing path + * getting lower and lower */ + if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { + params.radius = make_float3(0.0f, 0.0f, 0.0f); } - bssrdf = bssrdf_alloc(sd, make_float3(0.0f, weight.y, 0.0f)); - if(bssrdf) { - bssrdf->sample_weight = sample_weight; - bssrdf->radius = radius.y; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.y; - bssrdf->sharpness = sharpness; - bssrdf->N = params.N; - bssrdf->roughness = params.roughness; - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)type); - } - - bssrdf = bssrdf_alloc(sd, make_float3(0.0f, 0.0f, weight.z)); - if(bssrdf) { - bssrdf->sample_weight = sample_weight; - bssrdf->radius = radius.z; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.z; - bssrdf->sharpness = sharpness; - bssrdf->N = params.N; - bssrdf->roughness = params.roughness; - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)type); - } + /* create one closure per color channel */ + bssrdf->radius = params.radius; + bssrdf->albedo = params.albedo; + bssrdf->texture_blur = params.texture_blur; + bssrdf->sharpness = params.sharpness; + bssrdf->N = params.N; + bssrdf->roughness = params.roughness; + sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type); } } }; @@ -125,7 +90,7 @@ ClosureParam *closure_bssrdf_cubic_params() { static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, params.N), - CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, radius), + CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, params.radius), CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, params.texture_blur), CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, params.sharpness), CLOSURE_STRING_KEYPARAM(CubicBSSRDFClosure, label, "label"), @@ -150,7 +115,7 @@ ClosureParam *closure_bssrdf_gaussian_params() { static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, params.N), - CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, radius), + CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, params.radius), CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, params.texture_blur), CLOSURE_STRING_KEYPARAM(GaussianBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure) @@ -174,9 +139,9 @@ ClosureParam *closure_bssrdf_burley_params() { static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(BurleyBSSRDFClosure, params.N), - CLOSURE_FLOAT3_PARAM(BurleyBSSRDFClosure, radius), + CLOSURE_FLOAT3_PARAM(BurleyBSSRDFClosure, params.radius), CLOSURE_FLOAT_PARAM(BurleyBSSRDFClosure, params.texture_blur), - CLOSURE_FLOAT3_PARAM(BurleyBSSRDFClosure, albedo), + CLOSURE_FLOAT3_PARAM(BurleyBSSRDFClosure, params.albedo), CLOSURE_STRING_KEYPARAM(BurleyBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(BurleyBSSRDFClosure) }; @@ -199,9 +164,9 @@ ClosureParam *closure_bssrdf_principled_params() { static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(PrincipledBSSRDFClosure, params.N), - CLOSURE_FLOAT3_PARAM(PrincipledBSSRDFClosure, radius), + CLOSURE_FLOAT3_PARAM(PrincipledBSSRDFClosure, params.radius), CLOSURE_FLOAT_PARAM(PrincipledBSSRDFClosure, params.texture_blur), - CLOSURE_FLOAT3_PARAM(PrincipledBSSRDFClosure, albedo), + CLOSURE_FLOAT3_PARAM(PrincipledBSSRDFClosure, params.albedo), CLOSURE_FLOAT_PARAM(PrincipledBSSRDFClosure, params.roughness), CLOSURE_STRING_KEYPARAM(PrincipledBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(PrincipledBSSRDFClosure) diff --git a/intern/cycles/kernel/split/kernel_subsurface_scatter.h b/intern/cycles/kernel/split/kernel_subsurface_scatter.h index 5bf7483e9a2..38dd1dc5654 100644 --- a/intern/cycles/kernel/split/kernel_subsurface_scatter.h +++ b/intern/cycles/kernel/split/kernel_subsurface_scatter.h @@ -54,7 +54,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it branched_state->lcg_state = lcg_state_init_addrspace(&branched_state->path_state, 0x68bc21eb); } - int num_samples = kernel_data.integrator.subsurface_samples; + int num_samples = kernel_data.integrator.subsurface_samples * 3; float num_samples_inv = 1.0f/num_samples; uint bssrdf_rng_hash = cmj_hash(branched_state->path_state.rng_hash, i); diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 47ebe4288e3..5a5cf2db401 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -153,7 +153,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * #ifdef __SUBSURFACE__ float3 mixed_ss_base_color = subsurface_color * subsurface + base_color * (1.0f - subsurface); float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight; - float subsurf_sample_weight = fabsf(average(subsurf_weight)); /* disable in case of diffuse ancestor, can't see it well then and * adds considerably noise due to probabilities of continuing path @@ -182,55 +181,19 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * sd->flag |= bsdf_principled_diffuse_setup(bsdf); } } - else if(subsurface > CLOSURE_WEIGHT_CUTOFF && subsurf_sample_weight > CLOSURE_WEIGHT_CUTOFF) { - /* radius * scale */ - float3 radius = subsurface_radius * subsurface; - /* sharpness */ - float sharpness = 0.0f; - /* texture color blur */ - float texture_blur = 0.0f; - - /* create one closure per color channel */ - Bssrdf *bssrdf = bssrdf_alloc(sd, make_float3(subsurf_weight.x, 0.0f, 0.0f)); - if(bssrdf) { - bssrdf->sample_weight = subsurf_sample_weight; - bssrdf->radius = radius.x; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = subsurface_color.x; - bssrdf->sharpness = sharpness; - bssrdf->N = N; - bssrdf->roughness = roughness; - - /* setup bsdf */ - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_PRINCIPLED_ID); - } - - bssrdf = bssrdf_alloc(sd, make_float3(0.0f, subsurf_weight.y, 0.0f)); - if(bssrdf) { - bssrdf->sample_weight = subsurf_sample_weight; - bssrdf->radius = radius.y; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = subsurface_color.y; - bssrdf->sharpness = sharpness; - bssrdf->N = N; - bssrdf->roughness = roughness; - - /* setup bsdf */ - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_PRINCIPLED_ID); - } + else if(subsurface > CLOSURE_WEIGHT_CUTOFF) { + Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight); - bssrdf = bssrdf_alloc(sd, make_float3(0.0f, 0.0f, subsurf_weight.z)); if(bssrdf) { - bssrdf->sample_weight = subsurf_sample_weight; - bssrdf->radius = radius.z; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = subsurface_color.z; - bssrdf->sharpness = sharpness; + bssrdf->radius = subsurface_radius * subsurface; + bssrdf->albedo = subsurface_color; + bssrdf->texture_blur = 0.0f; + bssrdf->sharpness = 0.0f; bssrdf->N = N; bssrdf->roughness = roughness; /* setup bsdf */ - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)CLOSURE_BSSRDF_PRINCIPLED_ID); + sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)CLOSURE_BSSRDF_PRINCIPLED_ID); } } } @@ -784,57 +747,22 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSSRDF_CUBIC_ID: case CLOSURE_BSSRDF_GAUSSIAN_ID: case CLOSURE_BSSRDF_BURLEY_ID: { - float3 albedo = sd->svm_closure_weight; float3 weight = sd->svm_closure_weight * mix_weight; - float sample_weight = fabsf(average(weight)); - - /* disable in case of diffuse ancestor, can't see it well then and - * adds considerably noise due to probabilities of continuing path - * getting lower and lower */ - if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) - param1 = 0.0f; - - if(sample_weight > CLOSURE_WEIGHT_CUTOFF) { - /* radius * scale */ - float3 radius = stack_load_float3(stack, data_node.z)*param1; - /* sharpness */ - float sharpness = stack_load_float(stack, data_node.w); - /* texture color blur */ - float texture_blur = param2; - - /* create one closure per color channel */ - Bssrdf *bssrdf = bssrdf_alloc(sd, make_float3(weight.x, 0.0f, 0.0f)); - if(bssrdf) { - bssrdf->sample_weight = sample_weight; - bssrdf->radius = radius.x; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.x; - bssrdf->sharpness = sharpness; - bssrdf->N = N; - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)type); - } - - bssrdf = bssrdf_alloc(sd, make_float3(0.0f, weight.y, 0.0f)); - if(bssrdf) { - bssrdf->sample_weight = sample_weight; - bssrdf->radius = radius.y; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.y; - bssrdf->sharpness = sharpness; - bssrdf->N = N; - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)type); - } - - bssrdf = bssrdf_alloc(sd, make_float3(0.0f, 0.0f, weight.z)); - if(bssrdf) { - bssrdf->sample_weight = sample_weight; - bssrdf->radius = radius.z; - bssrdf->texture_blur = texture_blur; - bssrdf->albedo = albedo.z; - bssrdf->sharpness = sharpness; - bssrdf->N = N; - sd->flag |= bssrdf_setup(bssrdf, (ClosureType)type); - } + Bssrdf *bssrdf = bssrdf_alloc(sd, weight); + + if(bssrdf) { + /* disable in case of diffuse ancestor, can't see it well then and + * adds considerably noise due to probabilities of continuing path + * getting lower and lower */ + if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) + param1 = 0.0f; + + bssrdf->radius = stack_load_float3(stack, data_node.z)*param1; + bssrdf->albedo = sd->svm_closure_weight; + bssrdf->texture_blur = param2; + bssrdf->sharpness = stack_load_float(stack, data_node.w); + bssrdf->N = N; + sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type); } break; diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h index 67bf82b47a5..625c19c7c46 100644 --- a/intern/cycles/util/util_vector.h +++ b/intern/cycles/util/util_vector.h @@ -162,6 +162,11 @@ public: return memcmp(data_, other.data_, datasize_*sizeof(T)) == 0; } + bool operator!=(const array<T>& other) const + { + return !(*this == other); + } + void steal_data(array& from) { if(this != &from) { diff --git a/release/datafiles/blender_icons_update.py b/release/datafiles/blender_icons_update.py index f41505e2f6e..664915cc10b 100755 --- a/release/datafiles/blender_icons_update.py +++ b/release/datafiles/blender_icons_update.py @@ -2,13 +2,14 @@ # This script updates icons from the SVG file import os +import subprocess import sys def run(cmd): - print(" ", cmd) - os.system(cmd) + print(" ", " ".join(cmd)) + subprocess.check_call(cmd) -BASEDIR = os.path.abspath(os.path.dirname(__file__)) + os.sep +BASEDIR = os.path.abspath(os.path.dirname(__file__)) inkscape_bin = "inkscape" blender_bin = "blender" @@ -18,9 +19,24 @@ if sys.platform == 'darwin': if os.path.exists(inkscape_app_path): inkscape_bin = inkscape_app_path -cmd = inkscape_bin + ' "%sblender_icons.svg" --export-width=602 --export-height=640 --without-gui --export-png="%sblender_icons16.png"' % (BASEDIR, BASEDIR) +cmd = ( + inkscape_bin, + os.path.join(BASEDIR, "blender_icons.svg"), + "--export-width=602", + "--export-height=640", + "--without-gui", + "--export-png=" + os.path.join(BASEDIR, "blender_icons16.png"), +) run(cmd) -cmd = inkscape_bin + ' "%sblender_icons.svg" --export-width=1204 --export-height=1280 --without-gui --export-png="%sblender_icons32.png"' % (BASEDIR, BASEDIR) + +cmd = ( + inkscape_bin, + os.path.join(BASEDIR, "blender_icons.svg"), + "--export-width=1204", + "--export-height=1280", + "--without-gui", + "--export-png=" + os.path.join(BASEDIR, "blender_icons32.png"), +) run(cmd) @@ -32,40 +48,36 @@ datatoc_icon_split_py = os.path.join(BASEDIR, "..", "..", "source", "blender", " # create .dat pixmaps (which are stored in git) cmd = ( - blender_bin + " " - "--factory-startup --background -noaudio " - "--python " + datatoc_icon_split_py + " -- " - "--image=" + BASEDIR + "blender_icons16.png " - "--output=" + BASEDIR + "blender_icons16 " - "--output_prefix=icon16_ " - "--name_style=UI_ICONS " - "--parts_x 26 --parts_y 30 " - "--minx 3 --maxx 53 --miny 3 --maxy 8 " - "--minx_icon 2 --maxx_icon 2 --miny_icon 2 --maxy_icon 2 " - "--spacex_icon 1 --spacey_icon 1" - ) + blender_bin, "--background", "-noaudio", + "--python", datatoc_icon_split_py, "--", + "--image=" + os.path.join(BASEDIR, "blender_icons16.png"), + "--output=" + os.path.join(BASEDIR, "blender_icons16"), + "--output_prefix=icon16_", + "--name_style=UI_ICONS", + "--parts_x", "26", "--parts_y", "30", + "--minx", "3", "--maxx", "53", "--miny", "3", "--maxy", "8", + "--minx_icon", "2", "--maxx_icon", "2", "--miny_icon", "2", "--maxy_icon", "2", + "--spacex_icon", "1", "--spacey_icon", "1", +) run(cmd) cmd = ( - blender_bin + " " - "--factory-startup --background -noaudio " - "--python " + datatoc_icon_split_py + " -- " - "--image=" + BASEDIR + "blender_icons32.png " - "--output=" + BASEDIR + "blender_icons32 " - "--output_prefix=icon32_ " - "--name_style=UI_ICONS " - "--parts_x 26 --parts_y 30 " - "--minx 6 --maxx 106 --miny 6 --maxy 16 " - "--minx_icon 4 --maxx_icon 4 --miny_icon 4 --maxy_icon 4 " - "--spacex_icon 2 --spacey_icon 2" - - ) + blender_bin, "--background", "-noaudio", + "--python", datatoc_icon_split_py, "--", + "--image=" + os.path.join(BASEDIR, "blender_icons32.png"), + "--output=" + os.path.join(BASEDIR, "blender_icons32"), + "--output_prefix=icon32_", + "--name_style=UI_ICONS", + "--parts_x", "26", "--parts_y", "30", + "--minx", "6", "--maxx", "106", "--miny", "6", "--maxy", "16", + "--minx_icon", "4", "--maxx_icon", "4", "--miny_icon", "4", "--maxy_icon", "4", + "--spacex_icon", "2", "--spacey_icon", "2", +) run(cmd) -os.remove(BASEDIR + "blender_icons16.png") -os.remove(BASEDIR + "blender_icons32.png") +os.remove(os.path.join(BASEDIR, "blender_icons16.png")) +os.remove(os.path.join(BASEDIR, "blender_icons32.png")) # For testing, if we want the PNG of each image # ./datatoc_icon_split_to_png.py ./blender_icons16/*.dat # ./datatoc_icon_split_to_png.py ./blender_icons32/*.dat - diff --git a/release/datafiles/prvicons_update.py b/release/datafiles/prvicons_update.py index 448a43df9ce..bc170b98545 100755 --- a/release/datafiles/prvicons_update.py +++ b/release/datafiles/prvicons_update.py @@ -2,9 +2,10 @@ # This script updates icons from the SVG file import os +import subprocess import sys -BASEDIR = os.path.abspath(os.path.dirname(__file__)) + os.sep +BASEDIR = os.path.abspath(os.path.dirname(__file__)) inkscape_path = 'inkscape' @@ -13,5 +14,10 @@ if sys.platform == 'darwin': if os.path.exists(inkscape_app_path): inkscape_path = inkscape_app_path -cmd = inkscape_path + ' "%sprvicons.svg" --without-gui --export-png="%sprvicons.png"' % (BASEDIR, BASEDIR) -os.system(cmd) +cmd = ( + inkscape_path, + os.path.join(BASEDIR, "prvicons.svg"), + "--without-gui", + "--export-png=" + os.path.join(BASEDIR, "prvicons.png"), +) +subprocess.check_call(cmd) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f0d479e1d71..78719949afe 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -708,8 +708,10 @@ static void write_iddata(void *wd, const ID *id) static void write_previews(WriteData *wd, const PreviewImage *prv_orig) { - /* Never write previews when doing memsave (i.e. undo/redo)! */ - if (prv_orig && !wd->current) { + /* Note we write previews also for undo steps. It takes up some memory, + * but not doing so would causes all previews to be re-rendered after + * undo which is too expensive. */ + if (prv_orig) { PreviewImage prv = *prv_orig; /* don't write out large previews if not requested */ diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index d7e59a05772..bd2ad21d51c 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -75,7 +75,7 @@ static void createVertsTrisData(bContext *C, LinkNode *obs, DerivedMesh *dm; Scene *scene = CTX_data_scene(C); EvaluationContext eval_ctx; - LinkNode *dms = NULL; + LinkNodePair dms_pair = {NULL, NULL}; int nverts, ntris, *tris; float *verts; @@ -90,7 +90,7 @@ static void createVertsTrisData(bContext *C, LinkNode *obs, ob = (Object *) oblink->link; dm = mesh_create_derived_no_virtual(&eval_ctx, scene, ob, NULL, CD_MASK_MESH); DM_ensure_tessface(dm); - BLI_linklist_prepend(&dms, dm); + BLI_linklist_append(&dms_pair, dm); nverts += dm->getNumVerts(dm); nfaces = dm->getNumTessFaces(dm); @@ -106,6 +106,7 @@ static void createVertsTrisData(bContext *C, LinkNode *obs, *r_lay |= ob->lay; } + LinkNode *dms = dms_pair.list; /* create data */ verts = MEM_mallocN(sizeof(float) * 3 * nverts, "createVertsTrisData verts"); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 0fdd52d3205..1bee2716e65 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -633,7 +633,8 @@ static void node_common_set_butfunc(bNodeType *ntype) /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr, - PointerRNA *imaptr, PointerRNA *iuserptr) + PointerRNA *imaptr, PointerRNA *iuserptr, + bool compositor) { uiLayout *col; int source; @@ -668,7 +669,8 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr, uiItemR(col, ptr, "use_auto_refresh", 0, NULL, ICON_NONE); } - if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER && + if (compositor && + RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER && RNA_boolean_get(ptr, "has_layers")) { col = uiLayoutColumn(layout, false); @@ -792,7 +794,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA /* note: image user properties used directly here, unlike compositor image node, * which redefines them in the node struct RNA to get proper updates. */ - node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); + node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false); } static void node_shader_buts_tex_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -811,7 +813,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); - node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); + node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false); uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); uiItemR(layout, ptr, "interpolation", 0, "", ICON_NONE); @@ -1261,7 +1263,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * imaptr = RNA_pointer_get(ptr, "image"); - node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr); + node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr, true); node_buts_image_views(layout, C, ptr, &imaptr); } diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index b10ae4f6fe9..c4c4f4405a5 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -99,8 +99,8 @@ struct anim { int curtype; int curposition; /* index 0 = 1e, 1 = 2e, enz. */ int duration; - short frs_sec; - float frs_sec_base; + int frs_sec; + double frs_sec_base; int x, y; /* for number */ diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 25b0c0d7b1a..5472cae3ef2 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -55,6 +55,7 @@ #include <stdlib.h> #include <stdio.h> #include <math.h> +#include <limits.h> #ifndef _WIN32 #include <dirent.h> #else @@ -1365,16 +1366,32 @@ int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc) bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base) { + double frs_sec_base_double; if (anim->frs_sec) { - *frs_sec = anim->frs_sec; - *frs_sec_base = anim->frs_sec_base; + if (anim->frs_sec > SHRT_MAX) { + /* We cannot store original rational in our short/float format, + * we need to approximate it as best as we can... */ + *frs_sec = SHRT_MAX; + frs_sec_base_double = anim->frs_sec_base * (double)SHRT_MAX / (double)anim->frs_sec; + } + else { + *frs_sec = anim->frs_sec; + frs_sec_base_double = anim->frs_sec_base; + } #ifdef WITH_FFMPEG if (no_av_base) { - *frs_sec_base /= AV_TIME_BASE; + *frs_sec_base = (float)(frs_sec_base_double / AV_TIME_BASE); + } + else { + *frs_sec_base = (float)frs_sec_base_double; } #else UNUSED_VARS(no_av_base); + *frs_sec_base = (float)frs_sec_base_double; #endif + BLI_assert(*frs_sec > 0); + BLI_assert(*frs_sec_base > 0.0f); + return true; } return false; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 785f805a33e..5518b296e22 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -5676,14 +5676,16 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "fps", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "frs_sec"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 120); + RNA_def_property_range(prop, 1, SHRT_MAX); + RNA_def_property_ui_range(prop, 1, 120, 1, -1); RNA_def_property_ui_text(prop, "FPS", "Framerate, expressed in frames per second"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_fps_update"); prop = RNA_def_property(srna, "fps_base", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "frs_sec_base"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 0.1f, 120.0f); + RNA_def_property_range(prop, 1e-5f, 1e6f); + RNA_def_property_ui_range(prop, 0.1f, 120.0f, 2, -1); RNA_def_property_ui_text(prop, "FPS Base", "Framerate base"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_fps_update"); diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index 188b63d7d24..82077051c18 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -504,8 +504,11 @@ void RNA_api_wm(StructRNA *srna) /* invoke enum */ func = RNA_def_function(srna, "invoke_search_popup", "rna_Operator_enum_search_invoke"); - RNA_def_function_ui_description(func, "Operator search popup invoke (search in values of " - "operator's type 'prop' EnumProperty, and execute it on confirmation)"); + RNA_def_function_ui_description( + func, + "Operator search popup invoke which " + "searches values of the operator's :class:`bpy.types.Operator.bl_property` " + "(which must be an EnumProperty), executing it on confirmation"); rna_generic_op_invoke(func, 0); /* invoke functions, for use with python */ diff --git a/tests/python/pep8.py b/tests/python/pep8.py index dde4250f6aa..ebf2c5eabb7 100644 --- a/tests/python/pep8.py +++ b/tests/python/pep8.py @@ -19,6 +19,8 @@ # <pep8-80 compliant> import os +import subprocess +import shutil # depends on pep8, frosted, pylint # for Ubuntu @@ -71,6 +73,79 @@ def is_pep8(path): return 0 +def check_files_flake8(files): + print("\n\n\n# running flake8...") + + # these are very picky and often hard to follow + # while keeping common script formatting. + ignore = ( + "E122", + "E123", + "E124", + "E125", + "E126", + "E127", + "E128", + # "imports not at top of file." + # prefer to load as needed (lazy load addons etc). + "E402", + # "do not compare types, use 'isinstance()'" + # times types are compared, + # I rather keep them specific + "E721", + ) + + for f, pep8_type in files: + + if pep8_type == 1: + # E501:80 line length + ignore_tmp = ignore + ("E501", ) + else: + ignore_tmp = ignore + + subprocess.call(( + "flake8", + "--isolated", + "--ignore=%s" % ",".join(ignore_tmp), + f, + )) + + +def check_files_frosted(files): + print("\n\n\n# running frosted...") + for f, pep8_type in files: + subprocess.call(("frosted", f)) + + +def check_files_pylint(files): + print("\n\n\n# running pylint...") + for f, pep8_type in files: + # let pep8 complain about line length + subprocess.call(( + "pylint", + "--disable=" + "C0111," # missing doc string + "C0103," # invalid name + "C0413," # import should be placed at the top + "W0613," # unused argument, may add this back + # but happens a lot for 'context' for eg. + "W0232," # class has no __init__, Operator/Panel/Menu etc + "W0142," # Used * or ** magic + # even needed in some cases + "R0902," # Too many instance attributes + "R0903," # Too many statements + "R0911," # Too many return statements + "R0912," # Too many branches + "R0913," # Too many arguments + "R0914," # Too many local variables + "R0915,", # Too many statements + "--output-format=parseable", + "--reports=n", + "--max-line-length=1000", + f, + )) + + def main(): files = [] files_skip = [] @@ -113,70 +188,21 @@ def main(): print("%s:%d:0: empty class (), remove" % (f, i + 1)) del re, class_check - print("\n\n\n# running flake8...") - - # these are very picky and often hard to follow - # while keeping common script formatting. - ignore = ( - "E122", - "E123", - "E124", - "E125", - "E126", - "E127", - "E128", - # "imports not at top of file." - # prefer to load as needed (lazy load addons etc). - "E402", - # "do not compare types, use 'isinstance()'" - # times types are compared, - # I rather keep them specific - "E721", - ) - - for f, pep8_type in files: - - if pep8_type == 1: - # E501:80 line length - ignore_tmp = ignore + ("E501", ) - else: - ignore_tmp = ignore + if shutil.which("flake8"): + check_files_flake8(files) + else: + print("Skipping flake8 checks (command not found)") - os.system("flake8 " - "--isolated " - "--ignore=%s '%s'" % - (",".join(ignore_tmp), f)) + if shutil.which("frosted"): + check_files_frosted(files) + else: + print("Skipping frosted checks (command not found)") - # frosted - print("\n\n\n# running frosted...") - for f, pep8_type in files: - os.system("frosted '%s'" % f) + if shutil.which("pylint"): + check_files_pylint(files) + else: + print("Skipping pylint checks (command not found)") - print("\n\n\n# running pylint...") - for f, pep8_type in files: - # let pep8 complain about line length - os.system("pylint " - "--disable=" - "C0111," # missing doc string - "C0103," # invalid name - "C0413," # import should be placed at the top - "W0613," # unused argument, may add this back - # but happens a lot for 'context' for eg. - "W0232," # class has no __init__, Operator/Panel/Menu etc - "W0142," # Used * or ** magic - # even needed in some cases - "R0902," # Too many instance attributes - "R0903," # Too many statements - "R0911," # Too many return statements - "R0912," # Too many branches - "R0913," # Too many arguments - "R0914," # Too many local variables - "R0915," # Too many statements - " " - "--output-format=parseable " - "--reports=n " - "--max-line-length=1000" - " '%s'" % f) if __name__ == "__main__": |