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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild_files/cmake/example_scripts/make_quicky.py8
-rwxr-xr-xbuild_files/cmake/project_info.py21
-rw-r--r--doc/python_api/examples/bpy.types.Operator.6.py38
-rw-r--r--intern/cycles/blender/blender_mesh.cpp40
-rw-r--r--intern/cycles/kernel/closure/bssrdf.h165
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h2
-rw-r--r--intern/cycles/kernel/kernel_path_state.h8
-rw-r--r--intern/cycles/kernel/kernel_shader.h14
-rw-r--r--intern/cycles/kernel/kernel_subsurface.h48
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.cpp79
-rw-r--r--intern/cycles/kernel/split/kernel_subsurface_scatter.h2
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h116
-rw-r--r--intern/cycles/util/util_vector.h5
-rwxr-xr-xrelease/datafiles/blender_icons_update.py78
-rwxr-xr-xrelease/datafiles/prvicons_update.py12
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/editors/mesh/mesh_navmesh.c5
-rw-r--r--source/blender/editors/space_node/drawnode.c12
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h4
-rw-r--r--source/blender/imbuf/intern/anim_movie.c23
-rw-r--r--source/blender/makesrna/intern/rna_scene.c6
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c7
-rw-r--r--tests/python/pep8.py148
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__":