diff options
95 files changed, 815 insertions, 633 deletions
diff --git a/GNUmakefile b/GNUmakefile index 3c2ab9d51b9..c73aaa7bfbb 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -122,7 +122,7 @@ endif # Build Blender all: FORCE @echo - @echo Configuring Blender ... + @echo Configuring Blender in \"$(BUILD_DIR)\" ... # # if test ! -f $(BUILD_DIR)/CMakeCache.txt ; then \ # # $(CMAKE_CONFIG); \ diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 5a6aa5ca63e..2d839858b80 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -35,6 +35,8 @@ required-numpy: \ -- "$@" \ ) +COMMANDLINE=$@ + DISTRO="" RPM="" SRC="$HOME/src/blender-deps" @@ -2536,7 +2538,7 @@ install_RPM() { if $NUMPY_SKIP; then WARNING "Skipping NumPy installation, as requested..." else - check_package_version_match_RPM python3-numpy $NUMPY_VERSION_MIN + check_package_version_ge_RPM python3-numpy $NUMPY_VERSION_MIN if [ $? -eq 0 ]; then install_packages_RPM python3-numpy elif $NUMPY_REQUIRED; then @@ -3120,6 +3122,10 @@ print_info() { PRINT "Often, changes in the libs built by this script, or in your distro package, cannot be handled simply, so..." PRINT "" PRINT "" + PRINT "Ran with:" + PRINT " install_deps.sh $COMMANDLINE" + PRINT "" + PRINT "" PRINT "If you're using CMake add this to your configuration flags:" _buildargs="" diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 23d0d850cde..5f65fd7506b 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -463,11 +463,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Use BVH spatial splits: longer builder time, faster render", default=False, ) - cls.use_cache = BoolProperty( - name="Cache BVH", - description="Cache last built BVH to disk for faster re-render if no geometry changed", - default=False, - ) cls.tile_order = EnumProperty( name="Tile Order", description="Tile order for rendering", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 74e22303fac..feaabf17af5 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -332,7 +332,6 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): col.separator() col.label(text="Final Render:") - col.prop(cscene, "use_cache") col.prop(rd, "use_persistent_data", text="Persistent Images") col.separator() diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 8888d219aac..aed1b6de138 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -427,7 +427,6 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background, bo params.bvh_type = (SceneParams::BVHType)RNA_enum_get(&cscene, "debug_bvh_type"); params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits"); - params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false; if(background && params.shadingsystem != SHADINGSYSTEM_OSL) params.persistent_data = r.use_persistent_data(); diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 350ca16f6e2..4a5f8b1bda6 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -25,7 +25,6 @@ #include "bvh_node.h" #include "bvh_params.h" -#include "util_cache.h" #include "util_debug.h" #include "util_foreach.h" #include "util_logging.h" @@ -70,125 +69,12 @@ BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects) return new RegularBVH(params, objects); } -/* Cache */ - -bool BVH::cache_read(CacheData& key) -{ - key.add(system_cpu_bits()); - key.add(¶ms, sizeof(params)); - - foreach(Object *ob, objects) { - Mesh *mesh = ob->mesh; - - key.add(mesh->verts); - key.add(mesh->triangles); - key.add(mesh->curve_keys); - key.add(mesh->curves); - key.add(&ob->bounds, sizeof(ob->bounds)); - key.add(&ob->visibility, sizeof(ob->visibility)); - key.add(&mesh->transform_applied, sizeof(bool)); - - if(mesh->use_motion_blur) { - Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if(attr) - key.add(attr->buffer); - - attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if(attr) - key.add(attr->buffer); - } - } - - CacheData value; - - if(Cache::global.lookup(key, value)) { - cache_filename = key.get_filename(); - - if(!(value.read(pack.root_index) && - value.read(pack.SAH) && - value.read(pack.nodes) && - value.read(pack.leaf_nodes) && - value.read(pack.object_node) && - value.read(pack.tri_woop) && - value.read(pack.prim_type) && - value.read(pack.prim_visibility) && - value.read(pack.prim_index) && - value.read(pack.prim_object))) - { - /* Clear the pack if load failed. */ - pack.root_index = 0; - pack.SAH = 0.0f; - pack.nodes.clear(); - pack.leaf_nodes.clear(); - pack.object_node.clear(); - pack.tri_woop.clear(); - pack.prim_type.clear(); - pack.prim_visibility.clear(); - pack.prim_index.clear(); - pack.prim_object.clear(); - return false; - } - return true; - } - - return false; -} - -void BVH::cache_write(CacheData& key) -{ - CacheData value; - - value.add(pack.root_index); - value.add(pack.SAH); - - value.add(pack.nodes); - value.add(pack.leaf_nodes); - value.add(pack.object_node); - value.add(pack.tri_woop); - value.add(pack.prim_type); - value.add(pack.prim_visibility); - value.add(pack.prim_index); - value.add(pack.prim_object); - - Cache::global.insert(key, value); - - cache_filename = key.get_filename(); -} - -void BVH::clear_cache_except() -{ - set<string> except; - - if(!cache_filename.empty()) - except.insert(cache_filename); - - foreach(Object *ob, objects) { - Mesh *mesh = ob->mesh; - BVH *bvh = mesh->bvh; - - if(bvh && !bvh->cache_filename.empty()) - except.insert(bvh->cache_filename); - } - - Cache::global.clear_except("bvh", except); -} - /* Building */ void BVH::build(Progress& progress) { progress.set_substatus("Building BVH"); - /* cache read */ - CacheData key("bvh"); - - if(params.use_cache) { - progress.set_substatus("Looking in BVH cache"); - - if(cache_read(key)) - return; - } - /* build nodes */ BVHBuild bvh_build(objects, pack.prim_type, @@ -227,18 +113,6 @@ void BVH::build(Progress& progress) /* free build nodes */ root->deleteSubtree(); - - if(progress.get_cancel()) return; - - /* cache write */ - if(params.use_cache) { - progress.set_substatus("Writing BVH cache"); - cache_write(key); - - /* clear other bvh files from cache */ - if(params.top_level) - clear_cache_except(); - } } /* Refitting */ diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h index 669d2ccdcd5..272a3fa1514 100644 --- a/intern/cycles/bvh/bvh.h +++ b/intern/cycles/bvh/bvh.h @@ -20,7 +20,6 @@ #include "bvh_params.h" -#include "util_string.h" #include "util_types.h" #include "util_vector.h" @@ -30,7 +29,6 @@ class BVHNode; struct BVHStackEntry; class BVHParams; class BoundBox; -class CacheData; class LeafNode; class Object; class Progress; @@ -87,7 +85,6 @@ public: PackedBVH pack; BVHParams params; vector<Object*> objects; - string cache_filename; static BVH *create(const BVHParams& params, const vector<Object*>& objects); virtual ~BVH() {} @@ -95,15 +92,9 @@ public: void build(Progress& progress); void refit(Progress& progress); - void clear_cache_except(); - protected: BVH(const BVHParams& params, const vector<Object*>& objects); - /* cache */ - bool cache_read(CacheData& key); - void cache_write(CacheData& key); - /* triangles and strands*/ void pack_primitives(); void pack_triangle(int idx, float4 woop[3]); diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h index af8d8eeb3ee..faa995c3f29 100644 --- a/intern/cycles/bvh/bvh_params.h +++ b/intern/cycles/bvh/bvh_params.h @@ -43,9 +43,6 @@ public: /* object or mesh level bvh */ bool top_level; - /* disk cache */ - bool use_cache; - /* QBVH */ bool use_qbvh; @@ -71,7 +68,6 @@ public: max_curve_leaf_size = 2; top_level = false; - use_cache = false; use_qbvh = false; } diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index c3392d27b2c..a7157e2b041 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -313,7 +313,7 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) continue; } if(!opencl_device_version_check(device_id)) { - FIRST_VLOG(2) << "Ignoting device " << device_name + FIRST_VLOG(2) << "Ignoring device " << device_name << " due to old compiler version."; continue; } @@ -327,8 +327,8 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) &device_type, NULL) != CL_SUCCESS) { - FIRST_VLOG(2) << "Ignoting device " << device_name - << ", faield to fetch device type."; + FIRST_VLOG(2) << "Ignoring device " << device_name + << ", failed to fetch device type."; continue; } FIRST_VLOG(2) << "Adding new device " << device_name << "."; @@ -339,7 +339,7 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) device_name)); } else { - FIRST_VLOG(2) << "Ignoting device " << device_name + FIRST_VLOG(2) << "Ignoring device " << device_name << ", not officially supported yet."; } } diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index 2facced0914..4d70bc80006 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -77,7 +77,7 @@ public: ClosureParam *closure_background_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"), CLOSURE_FINISH_PARAM(GenericBackgroundClosure) }; return params; @@ -98,7 +98,7 @@ CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure) ClosureParam *closure_ambient_occlusion_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(AmbientOcclusionClosure, label, "label"), CLOSURE_FINISH_PARAM(AmbientOcclusionClosure) }; return params; diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp index 43929fbe928..b3c71e4a706 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp @@ -93,7 +93,7 @@ ClosureParam *closure_bsdf_diffuse_ramp_params() static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N), CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"), CLOSURE_FINISH_PARAM(DiffuseRampClosure) }; return params; diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp index 497c4f0dc5c..99f510d31ed 100644 --- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp @@ -93,7 +93,7 @@ ClosureParam *closure_bsdf_phong_ramp_params() CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N), CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0), CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"), CLOSURE_FINISH_PARAM(PhongRampClosure) }; return params; diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 02935542c56..9a95fa57a81 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -77,7 +77,7 @@ public: ClosureParam *closure_emission_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"), CLOSURE_FINISH_PARAM(GenericEmissiveClosure) }; return params; diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 88998037751..bc395922077 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -69,7 +69,7 @@ ClosureParam *closure_bssrdf_cubic_params() CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, radius), CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.data1), CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.T.x), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(CubicBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(CubicBSSRDFClosure) }; return params; @@ -97,7 +97,7 @@ ClosureParam *closure_bssrdf_gaussian_params() CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, sc.N), CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, radius), CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, sc.data1), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GaussianBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure) }; return params; diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index ef67ef52fc0..97bd1b1ac92 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -78,6 +78,11 @@ void name(RendererServices *, int id, void *data) \ #define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z) #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) +#if OSL_LIBRARY_VERSION_CODE < 10700 +# undef CLOSURE_STRING_KEYPARAM +# define CLOSURE_STRING_KEYPARAM(st, fld, key) { TypeDesc::TypeString, 0, key, 0 } +#endif + /* Closure */ class CClosurePrimitive { @@ -97,6 +102,10 @@ public: virtual void setup() {} Category category; + +#if OSL_LIBRARY_VERSION_CODE >= 10700 + OSL::ustring label; +#endif }; /* BSDF */ @@ -175,7 +184,7 @@ static ClosureParam *bsdf_##lower##_params() \ /* parameters */ #define BSDF_CLOSURE_CLASS_END(Upper, lower) \ - CLOSURE_STRING_KEYPARAM("label"), \ + CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \ CLOSURE_FINISH_PARAM(Upper##Closure) \ }; \ return params; \ @@ -223,7 +232,7 @@ static ClosureParam *volume_##lower##_params() \ /* parameters */ #define VOLUME_CLOSURE_CLASS_END(Upper, lower) \ - CLOSURE_STRING_KEYPARAM("label"), \ + CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \ CLOSURE_FINISH_PARAM(Upper##Closure) \ }; \ return params; \ diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 8cfe0cbcbd4..2f234aa25ea 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -146,165 +146,175 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, /* OSL gives us a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { +#else + switch(closure->id) { +#endif + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); + break; + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); + flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); + break; + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - if(prim) { - ShaderClosure sc; + if(prim) { + ShaderClosure sc; #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight*TO_FLOAT3(comp->w); + weight = weight*TO_FLOAT3(comp->w); #endif - sc.weight = weight; + sc.weight = weight; - prim->setup(); + prim->setup(); - switch (prim->category) { - case CClosurePrimitive::BSDF: { - CBSDFClosure *bsdf = (CBSDFClosure *)prim; - int scattering = bsdf->scattering(); + switch(prim->category) { + case CClosurePrimitive::BSDF: { + CBSDFClosure *bsdf = (CBSDFClosure *)prim; + int scattering = bsdf->scattering(); - /* caustic options */ - if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { - KernelGlobals *kg = sd->osl_globals; + /* caustic options */ + if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { + KernelGlobals *kg = sd->osl_globals; - if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || - (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { - return; + if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || + (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) + { + return; + } } - } - /* sample weight */ - float sample_weight = fabsf(average(weight)); + /* sample weight */ + float sample_weight = fabsf(average(weight)); - sc.sample_weight = sample_weight; + sc.sample_weight = sample_weight; - sc.type = bsdf->sc.type; - sc.N = bsdf->sc.N; - sc.T = bsdf->sc.T; - sc.data0 = bsdf->sc.data0; - sc.data1 = bsdf->sc.data1; - sc.data2 = bsdf->sc.data2; - sc.prim = bsdf->sc.prim; + sc.type = bsdf->sc.type; + sc.N = bsdf->sc.N; + sc.T = bsdf->sc.T; + sc.data0 = bsdf->sc.data0; + sc.data1 = bsdf->sc.data1; + sc.data2 = bsdf->sc.data2; + sc.prim = bsdf->sc.prim; - /* add */ - if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= bsdf->shaderdata_flag(); - } - break; - } - case CClosurePrimitive::Emissive: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_EMISSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - /* flag */ - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_EMISSION; - } - break; - } - case CClosurePrimitive::AmbientOcclusion: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_AO; - } - break; - } - case CClosurePrimitive::Holdout: { - sc.sample_weight = 0.0f; - sc.type = CLOSURE_HOLDOUT_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_HOLDOUT; + /* add */ + if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) { + sd->closure[sd->num_closure++] = sc; + sd->flag |= bsdf->shaderdata_flag(); + } + break; } - break; - } - case CClosurePrimitive::BSSRDF: { - CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; - float sample_weight = fabsf(average(weight)); + case CClosurePrimitive::Emissive: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); - if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) { sc.sample_weight = sample_weight; - - sc.type = bssrdf->sc.type; - sc.N = bssrdf->sc.N; - sc.data1 = bssrdf->sc.data1; - sc.T.x = bssrdf->sc.T.x; + sc.type = CLOSURE_EMISSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; sc.prim = NULL; - /* 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) - bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f); - - /* create one closure for each color channel */ - if(fabsf(weight.x) > 0.0f) { - sc.weight = make_float3(weight.x, 0.0f, 0.0f); - sc.data0 = bssrdf->radius.x; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + /* flag */ + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_EMISSION; } + break; + } + case CClosurePrimitive::AmbientOcclusion: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); - if(fabsf(weight.y) > 0.0f) { - sc.weight = make_float3(0.0f, weight.y, 0.0f); - sc.data0 = bssrdf->radius.y; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + sc.sample_weight = sample_weight; + sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; + sc.prim = NULL; + + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_AO; } + break; + } + case CClosurePrimitive::Holdout: { + sc.sample_weight = 0.0f; + sc.type = CLOSURE_HOLDOUT_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; + sc.prim = NULL; - if(fabsf(weight.z) > 0.0f) { - sc.weight = make_float3(0.0f, 0.0f, weight.z); - sc.data0 = bssrdf->radius.z; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_HOLDOUT; + } + break; + } + case CClosurePrimitive::BSSRDF: { + CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; + float sample_weight = fabsf(average(weight)); + + if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) { + sc.sample_weight = sample_weight; + + sc.type = bssrdf->sc.type; + sc.N = bssrdf->sc.N; + sc.data1 = bssrdf->sc.data1; + sc.T.x = bssrdf->sc.T.x; + sc.prim = NULL; + + /* 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) + bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f); + + /* create one closure for each color channel */ + if(fabsf(weight.x) > 0.0f) { + sc.weight = make_float3(weight.x, 0.0f, 0.0f); + sc.data0 = bssrdf->radius.x; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } + + if(fabsf(weight.y) > 0.0f) { + sc.weight = make_float3(0.0f, weight.y, 0.0f); + sc.data0 = bssrdf->radius.y; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } + + if(fabsf(weight.z) > 0.0f) { + sc.weight = make_float3(0.0f, 0.0f, weight.z); + sc.data0 = bssrdf->radius.z; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } } + break; } - break; + case CClosurePrimitive::Background: + case CClosurePrimitive::Volume: + break; /* not relevant */ } - case CClosurePrimitive::Background: - case CClosurePrimitive::Volume: - break; /* not relevant */ } + break; } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); - flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); - } } void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) @@ -335,27 +345,33 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure) * is only one supported closure type at the moment, which has no evaluation * functions, so we just sum the weights */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - - if(prim && prim->category == CClosurePrimitive::Background) -#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - return TO_FLOAT3(comp->w); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { #else - return make_float3(1.0f, 1.0f, 1.0f); + switch(closure->id) { #endif - } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure); + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - return flatten_background_closure_tree(add->closureA) + - flatten_background_closure_tree(add->closureB); + return flatten_background_closure_tree(add->closureA) + + flatten_background_closure_tree(add->closureB); + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); + + if(prim && prim->category == CClosurePrimitive::Background) +#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS + return TO_FLOAT3(comp->w); +#else + return make_float3(1.0f, 1.0f, 1.0f); +#endif + } } return make_float3(0.0f, 0.0f, 0.0f); @@ -390,76 +406,84 @@ static void flatten_volume_closure_tree(ShaderData *sd, /* OSL gives us a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { +#else + switch(closure->id) { +#endif + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); + break; + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + flatten_volume_closure_tree(sd, add->closureA, weight); + flatten_volume_closure_tree(sd, add->closureB, weight); + break; + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - if(prim) { - ShaderClosure sc; + if(prim) { + ShaderClosure sc; #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight*TO_FLOAT3(comp->w); + weight = weight*TO_FLOAT3(comp->w); #endif - sc.weight = weight; - - prim->setup(); - - switch (prim->category) { - case CClosurePrimitive::Volume: { - CVolumeClosure *volume = (CVolumeClosure *)prim; - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = volume->sc.type; - sc.data0 = volume->sc.data0; - sc.data1 = volume->sc.data1; - - /* add */ - if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) && - (sd->num_closure < MAX_CLOSURE)) - { - sd->closure[sd->num_closure++] = sc; - sd->flag |= volume->shaderdata_flag(); + sc.weight = weight; + + prim->setup(); + + switch(prim->category) { + case CClosurePrimitive::Volume: { + CVolumeClosure *volume = (CVolumeClosure *)prim; + /* sample weight */ + float sample_weight = fabsf(average(weight)); + + sc.sample_weight = sample_weight; + sc.type = volume->sc.type; + sc.data0 = volume->sc.data0; + sc.data1 = volume->sc.data1; + + /* add */ + if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) && + (sd->num_closure < MAX_CLOSURE)) + { + sd->closure[sd->num_closure++] = sc; + sd->flag |= volume->shaderdata_flag(); + } + break; } - break; - } - case CClosurePrimitive::Emissive: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_EMISSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.prim = NULL; - - /* flag */ - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_EMISSION; + case CClosurePrimitive::Emissive: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); + + sc.sample_weight = sample_weight; + sc.type = CLOSURE_EMISSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.prim = NULL; + + /* flag */ + if(sd->num_closure < MAX_CLOSURE) { + sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_EMISSION; + } + break; } - break; + case CClosurePrimitive::Holdout: + break; /* not implemented */ + case CClosurePrimitive::Background: + case CClosurePrimitive::BSDF: + case CClosurePrimitive::BSSRDF: + case CClosurePrimitive::AmbientOcclusion: + break; /* not relevant */ } - case CClosurePrimitive::Holdout: - break; /* not implemented */ - case CClosurePrimitive::Background: - case CClosurePrimitive::BSDF: - case CClosurePrimitive::BSSRDF: - case CClosurePrimitive::AmbientOcclusion: - break; /* not relevant */ } } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_volume_closure_tree(sd, add->closureA, weight); - flatten_volume_closure_tree(sd, add->closureB, weight); - } } void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 45685fe5927..57f194651f8 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -513,7 +513,6 @@ void Mesh::compute_bvh(SceneParams *params, Progress *progress, int n, int total progress->set_status(msg, "Building BVH"); BVHParams bparams; - bparams.use_cache = params->use_bvh_cache; bparams.use_spatial_split = params->use_bvh_spatial_split; bparams.use_qbvh = params->use_qbvh; @@ -1084,7 +1083,6 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene * bparams.top_level = true; bparams.use_qbvh = scene->params.use_qbvh; bparams.use_spatial_split = scene->params.use_bvh_spatial_split; - bparams.use_cache = scene->params.use_bvh_cache; delete bvh; bvh = BVH::create(bparams, scene->objects); diff --git a/intern/iksolver/intern/IK_Solver.cpp b/intern/iksolver/intern/IK_Solver.cpp index 65ea4d64ab1..eb18cde3356 100644 --- a/intern/iksolver/intern/IK_Solver.cpp +++ b/intern/iksolver/intern/IK_Solver.cpp @@ -292,6 +292,7 @@ void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float w IK_QSolver *qsolver = (IK_QSolver *)solver; IK_QSegment *qtip = (IK_QSegment *)tip; + // in case of composite segment the second segment is the tip if (qtip->Composite()) qtip = qtip->Composite(); @@ -310,6 +311,7 @@ void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[ IK_QSolver *qsolver = (IK_QSolver *)solver; IK_QSegment *qtip = (IK_QSegment *)tip; + // in case of composite segment the second segment is the tip if (qtip->Composite()) qtip = qtip->Composite(); @@ -331,6 +333,10 @@ void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float IK_QSolver *qsolver = (IK_QSolver *)solver; IK_QSegment *qtip = (IK_QSegment *)tip; + // in case of composite segment the second segment is the tip + if (qtip->Composite()) + qtip = qtip->Composite(); + MT_Vector3 qgoal(goal); MT_Vector3 qpolegoal(polegoal); diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc index 5d43cafd1f3..3fadde68d32 100644 --- a/intern/opensubdiv/opensubdiv_converter.cc +++ b/intern/opensubdiv/opensubdiv_converter.cc @@ -467,6 +467,14 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTags( break; } } + if (vert_edges.size() == 2) { + int edge0 = vert_edges[0], + edge1 = vert_edges[1]; + float sharpness0 = conv.get_edge_sharpness(&conv, edge0), + sharpness1 = conv.get_edge_sharpness(&conv, edge1); + float sharpness = std::min(sharpness0, sharpness1); + setBaseVertexSharpness(refiner, vert, sharpness); + } } return true; diff --git a/release/datafiles/locale b/release/datafiles/locale -Subproject de6c83e12e75ffaac90eddbd3cb7451b57c2e0c +Subproject c651e63a9a537624f639950f3127a1dee29205d diff --git a/release/scripts/addons b/release/scripts/addons -Subproject 94c9c4ee3370d1feb42fc978a1f0d2db07cb943 +Subproject 0eef469a5d444f396152376a49d7faad0ba51ab diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib -Subproject e31cec5bf243f00441c7dad7a775ec4722f829d +Subproject cf842d8bb7b0033ca4fa99f7ebedcbd3810fd27 diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index 78fb6aa8fa2..c2c306e5145 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -33,6 +33,7 @@ import bpy from bpy.props import ( BoolProperty, + BoolVectorProperty, FloatVectorProperty, ) @@ -136,16 +137,22 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name= if context.space_data and context.space_data.type == 'VIEW_3D': v3d = context.space_data - if use_active_layer: - if v3d and v3d.local_view: - base.layers_from_view(context.space_data) - base.layers[scene.active_layer] = True - else: - base.layers = [True if i == scene.active_layer - else False for i in range(len(scene.layers))] + if operator is not None and any(operator.layers): + base.layers = operator.layers else: - if v3d: - base.layers_from_view(context.space_data) + if use_active_layer: + if v3d and v3d.local_view: + base.layers_from_view(context.space_data) + base.layers[scene.active_layer] = True + else: + base.layers = [True if i == scene.active_layer + else False for i in range(len(scene.layers))] + else: + if v3d: + base.layers_from_view(context.space_data) + + if operator is not None: + operator.layers = base.layers obj_new.matrix_world = add_object_align_init(context, operator) @@ -209,6 +216,12 @@ class AddObjectHelper: name="Rotation", subtype='EULER', ) + layers = BoolVectorProperty( + name="Layers", + size=20, + subtype='LAYER', + options={'HIDDEN', 'SKIP_SAVE'}, + ) @classmethod def poll(self, context): diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index a14e34580c5..2c7f18b3dfe 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -229,6 +229,8 @@ class BONE_PT_display(BoneButtonsPanel, Panel): col.label(text="Custom Shape:") col.prop(pchan, "custom_shape", text="") if pchan.custom_shape: + col.prop(pchan, "use_custom_shape_bone_size", text="Bone Size") + col.prop(pchan, "custom_shape_scale", text="Scale") col.prop_search(pchan, "custom_shape_transform", ob.pose, "bones", text="At") diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 0b44f0eb317..3c5ae20d998 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -551,6 +551,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): if strip.input_count > 0: col = layout.column() + col.enabled = False col.prop(strip, "input_1") if strip.input_count > 1: col.prop(strip, "input_2") diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 3883b69c0d4..fad177df978 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -499,6 +499,11 @@ void DM_init( DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, int numFaces, int numLoops, int numPolys); +void DM_from_template_ex( + DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, + int numVerts, int numEdges, int numTessFaces, + int numLoops, int numPolys, + CustomDataMask mask); void DM_from_template( DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 327ae898686..bb00752db66 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 276 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 2 /* Several breakages with 270, e.g. constraint deg vs rad */ #define BLENDER_MINVERSION 270 #define BLENDER_MINSUBVERSION 5 diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index c7ad6419560..9948f21ba90 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -84,9 +84,15 @@ struct DerivedMesh *CDDM_copy_from_tessface(struct DerivedMesh *dm); * given DerivedMesh and containing the requested numbers of elements. * elements are initialized to all zeros */ -struct DerivedMesh *CDDM_from_template(struct DerivedMesh *source, - int numVerts, int numEdges, int numFaces, - int numLoops, int numPolys); +struct DerivedMesh *CDDM_from_template_ex( + struct DerivedMesh *source, + int numVerts, int numEdges, int numFaces, + int numLoops, int numPolys, + CustomDataMask mask); +struct DerivedMesh *CDDM_from_template( + struct DerivedMesh *source, + int numVerts, int numEdges, int numFaces, + int numLoops, int numPolys); /* converts mfaces to mpolys. note things may break if there are not valid * medges surrounding each mface. diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c index 006cebf4573..39669fd76d7 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c @@ -314,9 +314,12 @@ int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss) if (ss->osd_topology_refiner != NULL) { topology_refiner = ss->osd_topology_refiner; } - else { + else if (ss->osd_mesh != NULL) { topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh); } + else { + return 0; + } return openSubdiv_topologyRefinerGetNumFaces(topology_refiner); } @@ -327,9 +330,12 @@ int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face) if (ss->osd_topology_refiner != NULL) { topology_refiner = ss->osd_topology_refiner; } - else { + else if (ss->osd_mesh != NULL) { topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh); } + else { + return 0; + } return openSubdiv_topologyRefinerGetNumFaceVerts(topology_refiner, face); } diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index c48e5cf488b..20dabbdc323 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -328,21 +328,17 @@ void DM_init( * Utility function to initialize a DerivedMesh for the desired number * of vertices, edges and faces, with a layer setup copied from source */ -void DM_from_template( +void DM_from_template_ex( DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, int numVerts, int numEdges, int numTessFaces, - int numLoops, int numPolys) + int numLoops, int numPolys, + CustomDataMask mask) { - CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH, - CD_CALLOC, numVerts); - CustomData_copy(&source->edgeData, &dm->edgeData, CD_MASK_DERIVEDMESH, - CD_CALLOC, numEdges); - CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH, - CD_CALLOC, numTessFaces); - CustomData_copy(&source->loopData, &dm->loopData, CD_MASK_DERIVEDMESH, - CD_CALLOC, numLoops); - CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH, - CD_CALLOC, numPolys); + CustomData_copy(&source->vertData, &dm->vertData, mask, CD_CALLOC, numVerts); + CustomData_copy(&source->edgeData, &dm->edgeData, mask, CD_CALLOC, numEdges); + CustomData_copy(&source->faceData, &dm->faceData, mask, CD_CALLOC, numTessFaces); + CustomData_copy(&source->loopData, &dm->loopData, mask, CD_CALLOC, numLoops); + CustomData_copy(&source->polyData, &dm->polyData, mask, CD_CALLOC, numPolys); dm->cd_flag = source->cd_flag; @@ -358,6 +354,17 @@ void DM_from_template( dm->needsFree = 1; dm->dirty = 0; } +void DM_from_template( + DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, + int numVerts, int numEdges, int numTessFaces, + int numLoops, int numPolys) +{ + DM_from_template_ex( + dm, source, type, + numVerts, numEdges, numTessFaces, + numLoops, numPolys, + CD_MASK_DERIVEDMESH); +} int DM_release(DerivedMesh *dm) { @@ -3052,7 +3059,7 @@ static void GetNormal(const SMikkTSpaceContext *pContext, float r_no[3], const i } } else { - const short *no = pMesh->mvert[pMesh->mloop[lt->tri[0]].v].no; + const short *no = pMesh->mvert[pMesh->mloop[lt->tri[vert_index]].v].no; normal_short_to_float_v3(r_no, no); } } diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 5b1a6ea7a51..b77ae45e94d 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -485,6 +485,9 @@ bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name) chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel"); BLI_strncpy(chan->name, name, sizeof(chan->name)); + + chan->custom_scale = 1.0f; + /* init vars to prevent math errors */ unit_qt(chan->quat); unit_axis_angle(chan->rotAxis, &chan->rotAngle); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index c23595b6ee1..6afe7f1abe9 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2225,11 +2225,12 @@ bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden !((use_select == true) && ((pchan->bone->flag & BONE_SELECTED) == 0)))) { bPoseChannel *pchan_tx = (pchan->custom && pchan->custom_tx) ? pchan->custom_tx : pchan; - BoundBox *bb_custom = pchan->custom ? BKE_object_boundbox_get(pchan->custom) : NULL; - + BoundBox *bb_custom = ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) ? + BKE_object_boundbox_get(pchan->custom) : NULL; if (bb_custom) { - float mat[4][4]; - mul_m4_m4m4(mat, ob->obmat, pchan_tx->pose_mat); + float mat[4][4], smat[4][4]; + scale_m4_fl(smat, PCHAN_CUSTOM_DRAW_SIZE(pchan)); + mul_m4_series(mat, ob->obmat, pchan_tx->pose_mat, smat); BKE_boundbox_minmax(bb_custom, mat, r_min, r_max); } else { diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 0923ac7e743..9aad3cf564b 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -417,6 +417,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath BKE_scene_set_background(G.main, curscene); if (mode != LOAD_UNDO) { + RE_FreeAllPersistentData(); IMB_colormanagement_check_file_config(G.main); } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 489e26c5cbe..64b9bf48c98 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -80,6 +80,9 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, float priority = 0.0f, len = 0.0f; int ret = 0; + int p = 0; + efd.index = cur_efd.index = &p; + pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint); /* first find out goal/predator with highest priority */ @@ -1006,9 +1009,11 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) case eBoidRulesetType_Random: { /* use random rule for each particle (always same for same particle though) */ - rule = BLI_findlink(&state->rules, rand % BLI_listbase_count(&state->rules)); - - apply_boid_rule(bbd, rule, &val, pa, -1.0); + const int n = BLI_listbase_count(&state->rules); + if (n) { + rule = BLI_findlink(&state->rules, rand % n); + apply_boid_rule(bbd, rule, &val, pa, -1.0); + } break; } case eBoidRulesetType_Average: diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index d8290999ed1..f94e4ec8187 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -2483,10 +2483,11 @@ DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source) /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct * relationship between mesh data this needs to be set by the caller. */ -DerivedMesh *CDDM_from_template( +DerivedMesh *CDDM_from_template_ex( DerivedMesh *source, int numVerts, int numEdges, int numTessFaces, - int numLoops, int numPolys) + int numLoops, int numPolys, + CustomDataMask mask) { CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest"); DerivedMesh *dm = &cddm->dm; @@ -2498,7 +2499,11 @@ DerivedMesh *CDDM_from_template( source->getPolyDataArray(source, CD_ORIGINDEX); /* this does a copy of all non mvert/medge/mface layers */ - DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys); + DM_from_template_ex( + dm, source, DM_TYPE_CDDM, + numVerts, numEdges, numTessFaces, + numLoops, numPolys, + mask); /* now add mvert/medge/mface layers */ CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts); @@ -2522,6 +2527,16 @@ DerivedMesh *CDDM_from_template( return dm; } +DerivedMesh *CDDM_from_template( + DerivedMesh *source, + int numVerts, int numEdges, int numTessFaces, + int numLoops, int numPolys) +{ + return CDDM_from_template_ex( + source, numVerts, numEdges, numTessFaces, + numLoops, numPolys, + CD_MASK_DERIVEDMESH); +} void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3]) { diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index ed50bdda744..0d43fc7a8d9 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1372,10 +1372,17 @@ const CustomDataMask CD_MASK_BMESH = CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS | CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK | CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE | - CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_FACEMAP; -const CustomDataMask CD_MASK_FACECORNERS = /* XXX Not used anywhere! */ - CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | - CD_MASK_MLOOPCOL | CD_MASK_NORMAL | CD_MASK_MLOOPTANGENT; + CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_FACEMAP; +/** + * cover values copied by #BKE_mesh_loops_to_tessdata + */ +const CustomDataMask CD_MASK_FACECORNERS = + CD_MASK_MTFACE | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | + CD_MASK_MCOL | CD_MASK_MLOOPCOL | + CD_MASK_PREVIEW_MCOL | CD_MASK_PREVIEW_MLOOPCOL | + CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | + CD_MASK_TESSLOOPNORMAL | CD_MASK_NORMAL | + CD_MASK_TANGENT | CD_MASK_MLOOPTANGENT; const CustomDataMask CD_MASK_EVERYTHING = CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_NORMAL /* | CD_MASK_POLYINDEX */ | CD_MASK_PROP_FLT | diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 7557015be8e..f3ce988ee17 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1773,8 +1773,8 @@ static DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, } else { col[l_index].r = - col[l_index].g = - col[l_index].b = FTOCHAR(pPoint[v_index].wetness); + col[l_index].g = + col[l_index].b = FTOCHAR(pPoint[v_index].wetness); col[l_index].a = 255; } } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index bf53acc1d95..e66fa86c4b1 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -687,10 +687,10 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin } static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p, int *step) { - if (eff->pd->shape == PFIELD_SHAPE_POINTS) { - efd->index = p; + *p = 0; + efd->index = p; - *p = 0; + if (eff->pd->shape == PFIELD_SHAPE_POINTS) { *tot = eff->ob->derivedFinal ? eff->ob->derivedFinal->numVertData : 1; if (*tot && eff->pd->forcefield == PFIELD_HARMONIC && point->index >= 0) { @@ -699,9 +699,6 @@ static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoin } } else if (eff->psys) { - efd->index = p; - - *p = 0; *tot = eff->psys->totpart; if (eff->pd->forcefield == PFIELD_CHARGE) { @@ -727,7 +724,6 @@ static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoin } } else { - *p = 0; *tot = 1; } } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index fa0d34b8db6..3e7e98b4a1d 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1078,7 +1078,10 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb) static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb) { bNode *node; - + + /* parses the geom+tex nodes */ + ntreeShaderGetTexcoMode(ntree, r_mode, &basemat->texco, &basemat->mode_l); + for (node = ntree->nodes.first; node; node = node->next) { if (node->id) { if (GS(node->id->name) == ID_MA) { @@ -1115,9 +1118,6 @@ void init_render_material(Material *mat, int r_mode, float *amb) mat->mode_l = (mat->mode & MA_MODE_PIPELINE) | MA_SHLESS; mat->mode2_l = mat->mode2 & MA_MODE2_PIPELINE; - /* parses the geom+tex nodes */ - ntreeShaderGetTexcoMode(mat->nodetree, r_mode, &mat->texco, &mat->mode_l); - init_render_nodetree(mat->nodetree, mat, r_mode, amb); if (!mat->nodetree->execdata) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 9ef5b697079..fbba6249b73 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -1464,10 +1464,10 @@ DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm, gridData = result->getGridData(result); result->getGridKey(result, &key); - subGridData = MEM_callocN(sizeof(CCGElem *) * numGrids, "subGridData*"); + subGridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "subGridData*"); for (i = 0; i < numGrids; i++) { - subGridData[i] = MEM_callocN(key.elem_size * gridSize * gridSize, "subGridData"); + subGridData[i] = MEM_mallocN(key.elem_size * gridSize * gridSize, "subGridData"); memcpy(subGridData[i], gridData[i], key.elem_size * gridSize * gridSize); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ed2fd034608..476c2ed3539 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1955,9 +1955,15 @@ void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat) } case ROT_MODE_AXISANGLE: { - mat3_to_axis_angle(ob->rotAxis, &ob->rotAngle, mat); - sub_v3_v3(ob->rotAxis, ob->drotAxis); - ob->rotAngle -= ob->drotAngle; + float quat[4]; + float dquat[4]; + + /* without drot we could apply 'mat' directly */ + mat3_to_quat(quat, mat); + axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle); + invert_qt(dquat); + mul_qt_qtqt(quat, dquat, quat); + quat_to_axis_angle(ob->rotAxis, &ob->rotAngle, quat); break; } default: /* euler */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f9ca66b443c..1ccc213006a 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -2174,8 +2174,8 @@ bool BKE_scene_use_new_shading_nodes(const Scene *scene) bool BKE_scene_use_shading_nodes_custom(Scene *scene) { - RenderEngineType *type = RE_engines_find(scene->r.engine); - return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM); + RenderEngineType *type = RE_engines_find(scene->r.engine); + return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM); } bool BKE_scene_uses_blender_internal(const Scene *scene) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 509ca9cdd19..05f658e0b2b 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -848,6 +848,11 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) int i, edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSize = ccgSubSurf_getGridSize(ss); + if (!ccgSubSurf_getNumVerts(ss)) { + r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0f; + return; + } + #ifdef WITH_OPENSUBDIV if (ccgdm->useGpuBackend) { ccgSubSurf_getMinMax(ccgdm->ss, r_min, r_max); @@ -857,9 +862,6 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) CCG_key_top_level(&key, ss); - if (!ccgSubSurf_getNumVerts(ss)) - r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0; - for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { CCGVert *v = ccgVertIterator_getCurrent(&vi); float *co = ccgSubSurf_getVertData(ss, v); diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index cec455e01b9..82e4405225a 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -147,7 +147,9 @@ bMovieHandle *BKE_movie_handle_get(const char imtype) #endif /* in case all above are disabled */ - (void)imtype;return &mh; + (void)imtype; + + return (mh.append_movie != append_stub) ? &mh : NULL; } /* ****************************************************************** */ @@ -298,8 +300,10 @@ static void context_free_avi(void *context_v) void BKE_movie_filepath_get(char *string, RenderData *rd, bool preview, const char *suffix) { bMovieHandle *mh = BKE_movie_handle_get(rd->im_format.imtype); - if (mh->get_movie_path) + if (mh && mh->get_movie_path) { mh->get_movie_path(string, rd, preview, suffix); - else + } + else { string[0] = '\0'; + } } diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index edda852a032..bc734a9a551 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -1234,15 +1234,6 @@ static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit) context->video_stream = 0; } - - /* Close the output file */ - if (context->outfile) { - for (i = 0; i < context->outfile->nb_streams; i++) { - if (&context->outfile->streams[i]) { - av_freep(&context->outfile->streams[i]); - } - } - } /* free the temp buffer */ if (context->current_frame) { delete_picture(context->current_frame); @@ -1254,7 +1245,7 @@ static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit) } } if (context->outfile) { - av_free(context->outfile); + avformat_free_context(context->outfile); context->outfile = 0; } if (context->audio_input_buffer) { diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 493c285d251..fc0dd76b003 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -307,7 +307,7 @@ MINLINE void normal_float_to_short_v3(short r[3], const float n[3]); void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]); void minmax_v2v2_v2(float min[2], float max[2], const float vec[2]); -void minmax_v3v3_v3_array(float r_min[3], float r_max[3], float (*vec_arr)[3], int nbr); +void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr)[3], int nbr); void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist); void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index dad2a2fc288..c3ae557d3d3 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -3570,8 +3570,8 @@ void perspective_m4(float mat[4][4], const float left, const float right, const mat[2][3] = -1.0f; mat[3][2] = (-2.0f * nearClip * farClip) / Zdelta; mat[0][1] = mat[0][2] = mat[0][3] = - mat[1][0] = mat[1][2] = mat[1][3] = - mat[3][0] = mat[3][1] = mat[3][3] = 0.0f; + mat[1][0] = mat[1][2] = mat[1][3] = + mat[3][0] = mat[3][1] = mat[3][3] = 0.0f; } diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 6da0e87355d..8d33e04241a 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -785,7 +785,7 @@ void minmax_v2v2_v2(float min[2], float max[2], const float vec[2]) if (max[1] < vec[1]) max[1] = vec[1]; } -void minmax_v3v3_v3_array(float r_min[3], float r_max[3], float (*vec_arr)[3], int nbr) +void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr)[3], int nbr) { while (nbr--) { minmax_v3v3_v3(r_min, r_max, *vec_arr++); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 7172327adac..0bff61d7b26 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -618,7 +618,9 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab m = BKE_main_new(); BLI_addtail(mainlist, m); - lib = BKE_libblock_alloc(m, ID_LI, "lib"); + /* Add library datablock itself to 'main' Main, since libraries are **never** linked data. + * Fixes bug where you could end with all ID_LI datablocks having the same name... */ + lib = BKE_libblock_alloc(mainlist->first, ID_LI, "Lib"); BLI_strncpy(lib->name, filepath, sizeof(lib->name)); BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath)); diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index a7e91e2b9fa..fabef392601 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -854,6 +854,21 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) #undef BRUSH_TORUS } + if (!MAIN_VERSION_ATLEAST(main, 276, 2)) { + if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "custom_scale")) { + Object *ob; + + for (ob = main->object.first; ob; ob = ob->id.next) { + if (ob->pose) { + bPoseChannel *pchan; + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + pchan->custom_scale = 1.0f; + } + } + } + } + } + { if (!DNA_struct_elem_find(fd->filesdna, "SpaceNode", "float", "backdrop_zoom")) { bScreen *sc; diff --git a/source/blender/depsgraph/intern/depsgraph_build_relations.cc b/source/blender/depsgraph/intern/depsgraph_build_relations.cc index 649105a0df2..c348adaaf53 100644 --- a/source/blender/depsgraph/intern/depsgraph_build_relations.cc +++ b/source/blender/depsgraph/intern/depsgraph_build_relations.cc @@ -812,6 +812,10 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) ComponentKey geometry_key(shape_key->from, DEPSNODE_TYPE_GEOMETRY); add_relation(driver_key, geometry_key, DEPSREL_TYPE_DRIVER, "[Driver -> ShapeKey Geom]"); } + else if (strstr(fcu->rna_path, "key_blocks[")) { + ComponentKey geometry_key(id, DEPSNODE_TYPE_GEOMETRY); + add_relation(driver_key, geometry_key, DEPSREL_TYPE_DRIVER, "[Driver -> ShapeKey Geom]"); + } else { if (GS(id->name) == ID_OB) { /* assume that driver affects a transform... */ diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc index 59351495df0..54980436733 100644 --- a/source/blender/depsgraph/intern/depsgraph_debug.cc +++ b/source/blender/depsgraph/intern/depsgraph_debug.cc @@ -345,9 +345,11 @@ static void deg_debug_graphviz_node_fillcolor(const DebugContext &ctx, #endif static void deg_debug_graphviz_relation_color(const DebugContext &ctx, - const DepsRelation *UNUSED(rel)) + const DepsRelation *rel) { - const char *defaultcolor = "black"; + const char *color_default = "black"; + const char *color_error = "red4"; + const char *color = color_default; #if 0 /* disabled for now, edge colors are hardly distinguishable */ int color = deg_debug_relation_type_color_index(rel->type); if (color < 0) { @@ -357,7 +359,10 @@ static void deg_debug_graphviz_relation_color(const DebugContext &ctx, deg_debug_fprintf(ctx, "\"%s\"", deg_debug_colors_dark[color % deg_debug_max_colors]); } #else - deg_debug_fprintf(ctx, "%s", defaultcolor); + if (rel->flag & DEPSREL_FLAG_CYCLIC) + color = color_error; + + deg_debug_fprintf(ctx, "%s", color); #endif } @@ -439,6 +444,7 @@ static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx, deg_debug_fprintf(ctx, "label=<%s>;" NL, name.c_str()); deg_debug_fprintf(ctx, "fontname=\"%s\";" NL, deg_debug_graphviz_fontname); deg_debug_fprintf(ctx, "fontsize=%f;" NL, deg_debug_graphviz_node_label_size); + deg_debug_fprintf(ctx, "margin=\"%d\";" NL, 16); deg_debug_fprintf(ctx, "style="); deg_debug_graphviz_node_style(ctx, node); deg_debug_fprintf(ctx, ";" NL); deg_debug_fprintf(ctx, "color="); deg_debug_graphviz_node_color(ctx, node); deg_debug_fprintf(ctx, ";" NL); deg_debug_fprintf(ctx, "fillcolor="); deg_debug_graphviz_node_fillcolor(ctx, node); deg_debug_fprintf(ctx, ";" NL); @@ -592,6 +598,8 @@ static void deg_debug_graphviz_node_relations(const DebugContext &ctx, { DEPSNODE_RELATIONS_ITER_BEGIN(node->inlinks, rel) { + float penwidth = 2.0f; + const DepsNode *tail = rel->to; /* same as node */ const DepsNode *head = rel->from; deg_debug_fprintf(ctx, "// %s -> %s\n", @@ -602,9 +610,20 @@ static void deg_debug_graphviz_node_relations(const DebugContext &ctx, deg_debug_fprintf(ctx, "\"node_%p\"", tail); deg_debug_fprintf(ctx, "["); + /* XXX labels on relations are not very helpful: + * - they tend to appear too far away to be associated with the edge lines + * - names are mostly redundant, reflecting simply their from/to nodes + * - no behavior or typing of relations themselves to justify labels + */ +#if 0 deg_debug_fprintf(ctx, "label=\"%s\"", rel->name); deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg_debug_graphviz_fontname); +#else + /* Note: without label an id seem necessary to avoid bugs in graphviz/dot */ + deg_debug_fprintf(ctx, "id=\"%s\"", rel->name); +#endif deg_debug_fprintf(ctx, ",color="); deg_debug_graphviz_relation_color(ctx, rel); + deg_debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth); /* NOTE: edge from node to own cluster is not possible and gives graphviz * warning, avoid this here by just linking directly to the invisible * placeholder node diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index f4575105426..dbbdae280f2 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -929,7 +929,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op) ob = obedit; arm = (bArmature *)ob->data; - ebone_active = arm->act_edbone; + ebone_active = arm->act_edbone; if (ebone_active == NULL) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 184482eeacb..df88da073ca 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -756,7 +756,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i) else if (i == gps->totpoints - 2) { /* allocate new points array, and assign most of the old stroke there */ gps->totpoints--; - gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->points = MEM_mallocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); memcpy(gps->points, pt_tmp, sizeof(bGPDspoint) * gps->totpoints); /* free temp buffer */ @@ -770,7 +770,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i) else if (i == 0) { /* allocate new points array, and assign most of the old stroke there */ gps->totpoints--; - gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->points = MEM_mallocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint) * gps->totpoints); /* We must adjust timings! @@ -807,7 +807,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i) BLI_insertlinkafter(&gpf->strokes, gps, gsn); gsn->totpoints = gps->totpoints - i; - gsn->points = MEM_callocN(sizeof(bGPDspoint) * gsn->totpoints, "gp_stroke_points"); + gsn->points = MEM_mallocN(sizeof(bGPDspoint) * gsn->totpoints, "gp_stroke_points"); memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint) * gsn->totpoints); /* We must adjust timings of this new stroke! @@ -831,8 +831,8 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i) /* adjust existing stroke */ gps->totpoints = i; - gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); - memcpy(gps->points, pt_tmp, sizeof(bGPDspoint) * i); + gps->points = MEM_mallocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + memcpy(gps->points, pt_tmp, sizeof(bGPDspoint) * gps->totpoints); /* free temp buffer */ MEM_freeN(pt_tmp); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 44e130ed896..1238b883e9a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -3484,7 +3484,8 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C) ui_abs = uiLayoutAbsolute(layout, false); block = uiLayoutGetBlock(ui_abs); - width = BLF_width(style->widget.uifont_id, report->message, report->len); + UI_fontstyle_set(&style->widgetlabel); + width = BLF_width(style->widgetlabel.uifont_id, report->message, report->len); width = min_ii((int)(rti->widthfac * width), width); width = max_ii(width, 10); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 4a7156d7216..4f5285fa2f9 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1077,7 +1077,7 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tima.face, 255, 255, 255, 10); rgba_char_args_set(btheme->tima.face_select, 255, 133, 0, 60); rgba_char_args_set(btheme->tima.editmesh_active, 255, 255, 255, 128); - rgba_char_args_set_fl(btheme->tima.preview_back, 0.45, 0.45, 0.45, 1.0); + rgba_char_args_set_fl(btheme->tima.preview_back, 0.0, 0.0, 0.0, 0.3); rgba_char_args_set_fl(btheme->tima.preview_stitch_face, 0.5, 0.5, 0.0, 0.2); rgba_char_args_set_fl(btheme->tima.preview_stitch_edge, 1.0, 0.0, 1.0, 0.2); rgba_char_args_set_fl(btheme->tima.preview_stitch_vert, 0.0, 0.0, 1.0, 0.2); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 787b79f0d6e..dbbf49a527b 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -209,6 +209,8 @@ typedef struct KnifeTool_OpData { bool is_ortho; float ortho_extent; + float ortho_extent_center[3]; + float clipsta, clipend; enum { @@ -1281,20 +1283,29 @@ static bool knife_ray_intersect_face( return false; } -/* Calculate maximum excursion from (0,0,0) of mesh */ +/** + * Calculate the center and maximum excursion of mesh. + */ static void calc_ortho_extent(KnifeTool_OpData *kcd) { BMIter iter; BMVert *v; BMesh *bm = kcd->em->bm; - float max_xyz = 0.0f; - int i; + float min[3], max[3]; + + INIT_MINMAX(min, max); - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - for (i = 0; i < 3; i++) - max_xyz = max_ff(max_xyz, fabsf(v->co[i])); + if (kcd->cagecos) { + minmax_v3v3_v3_array(min, max, kcd->cagecos, bm->totvert); } - kcd->ortho_extent = max_xyz; + else { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + minmax_v3v3_v3(min, max, v->co); + } + } + + kcd->ortho_extent = len_v3v3(min, max) / 2; + mid_v3_v3v3(kcd->ortho_extent_center, min, max); } static BMElem *bm_elem_from_knife_vert(KnifeVert *kfv, KnifeEdge **r_kfe) @@ -1482,14 +1493,20 @@ static bool point_is_visible( /* Clip the line (v1, v2) to planes perpendicular to it and distances d from * the closest point on the line to the origin */ -static void clip_to_ortho_planes(float v1[3], float v2[3], float d) +static void clip_to_ortho_planes(float v1[3], float v2[3], const float center[3], const float d) { - float closest[3]; - const float origin[3] = {0.0f, 0.0f, 0.0f}; + float closest[3], dir[3]; + + sub_v3_v3v3(dir, v1, v2); + normalize_v3(dir); + + /* could be v1 or v2 */ + sub_v3_v3(v1, center); + project_plane_v3_v3v3(closest, v1, dir); + add_v3_v3(closest, center); - closest_to_line_v3(closest, origin, v1, v2); - dist_ensure_v3_v3fl(v1, closest, d); - dist_ensure_v3_v3fl(v2, closest, d); + madd_v3_v3v3fl(v1, closest, dir, d); + madd_v3_v3v3fl(v2, closest, dir, -d); } static void set_linehit_depth(KnifeTool_OpData *kcd, KnifeLineHit *lh) @@ -1573,8 +1590,8 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd) if (kcd->is_ortho && (kcd->vc.rv3d->persp != RV3D_CAMOB)) { if (kcd->ortho_extent == 0.0f) calc_ortho_extent(kcd); - clip_to_ortho_planes(v1, v3, kcd->ortho_extent + 10.0f); - clip_to_ortho_planes(v2, v4, kcd->ortho_extent + 10.0f); + clip_to_ortho_planes(v1, v3, kcd->ortho_extent_center, kcd->ortho_extent + 10.0f); + clip_to_ortho_planes(v2, v4, kcd->ortho_extent_center, kcd->ortho_extent + 10.0f); } /* First use bvh tree to find faces, knife edges, and knife verts that might diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 112edef5120..7f22ff7c241 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -2389,6 +2389,15 @@ static bool select_linked_delimit_test( return false; } +static void select_linked_delimit_validate(BMesh *bm, int *delimit) +{ + if ((*delimit) & BMO_DELIM_UV) { + if (!CustomData_has_layer(&bm->ldata, CD_MLOOPUV)) { + (*delimit) &= ~BMO_DELIM_UV; + } + } +} + static void select_linked_delimit_begin(BMesh *bm, short selectmode, int delimit) { struct DelimitData delimit_data = {0}; @@ -2441,7 +2450,9 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) BMIter iter; BMWalker walker; - const int delimit = RNA_enum_get(op->ptr, "delimit"); + int delimit = RNA_enum_get(op->ptr, "delimit"); + + select_linked_delimit_validate(bm, &delimit); if (delimit) { select_linked_delimit_begin(em->bm, em->selectmode, delimit); @@ -2607,6 +2618,8 @@ static void edbm_select_linked_pick_ex( BMesh *bm = em->bm; BMWalker walker; + select_linked_delimit_validate(bm, &delimit); + if (delimit) { select_linked_delimit_begin(bm, em->selectmode, delimit); } diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index c718dfa9229..fe4022709de 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -706,7 +706,7 @@ static void screen_opengl_render_cancel(bContext *C, wmOperator *op) } /* share between invoke and exec */ -static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) +static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) { /* initialize animation */ OGLRender *oglrender; @@ -722,9 +722,16 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) size_t i, width, height; BKE_scene_multiview_videos_dimensions_get(&scene->r, oglrender->sizex, oglrender->sizey, &width, &height); - oglrender->movie_ctx_arr = MEM_mallocN(sizeof(void *) * oglrender->totvideos, "Movies"); oglrender->mh = BKE_movie_handle_get(scene->r.im_format.imtype); + if (oglrender->mh == NULL) { + BKE_report(oglrender->reports, RPT_ERROR, "Movie format unsupported"); + screen_opengl_render_end(C, oglrender); + return false; + } + + oglrender->movie_ctx_arr = MEM_mallocN(sizeof(void *) * oglrender->totvideos, "Movies"); + for (i = 0; i < oglrender->totvideos; i++) { const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, i); @@ -733,7 +740,7 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) oglrender->sizey, oglrender->reports, PRVRANGEON != 0, suffix)) { screen_opengl_render_end(C, oglrender); - return 0; + return false; } } } @@ -742,7 +749,7 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op) oglrender->nfra = PSFRA; scene->r.cfra = PSFRA; - return 1; + return true; } static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index e23ac1710e3..a701fc9ccb7 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -354,6 +354,10 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float if (BKE_imtype_is_movie(rd.im_format.imtype)) { mh = BKE_movie_handle_get(sj->scene->r.im_format.imtype); + if (mh == NULL) { + printf("Movie format unsupported\n"); + return; + } sj->movie_ctx = mh->context_create(); sj->movie_handle = mh; diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 3af210f376b..6b5cc38595b 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -644,7 +644,7 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes int wmenu1, wmenu2, wmenu3, wmenu4; const char *fake_name; const char *display_name = ""; - const bool show_stereo = (iuser->flag & IMA_SHOW_STEREO); + const bool show_stereo = (iuser->flag & IMA_SHOW_STEREO) != 0; uiLayoutRow(layout, true); @@ -702,7 +702,9 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes UI_but_type_set_menu_from_pulldown(but); /* view */ - if (BLI_listbase_count_ex(&rr->views, 2) > 1 && !show_stereo) { + if (BLI_listbase_count_ex(&rr->views, 2) > 1 && + ((!show_stereo) || (!RE_RenderResult_is_stereo(rr)))) + { rview = BLI_findlink(&rr->views, iuser->view); display_name = rview ? rview->name : ""; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 98a0752f64d..97e3390f142 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -919,7 +919,8 @@ static void image_tools_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ED_region_tag_redraw(ar); break; case NC_BRUSH: - if (wmn->action == NA_EDITED) + /* NA_SELECTED is used on brush changes */ + if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) ED_region_tag_redraw(ar); break; case NC_SCENE: diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c index 7286b6fbc0c..4097db29e5a 100644 --- a/source/blender/editors/space_node/node_relationships.c +++ b/source/blender/editors/space_node/node_relationships.c @@ -1634,12 +1634,36 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w NodeInsertOfsData *iofsd = snode->iofsd; bNode *node; float duration; + bool redraw = false; if (!snode || event->type != TIMER || iofsd->anim_timer != event->customdata) return OPERATOR_PASS_THROUGH; - /* end timer + free insert offset data */ duration = (float)iofsd->anim_timer->duration; + + /* handle animation - do this before possibly aborting due to duration, since + * main thread might be so busy that node hasn't reached final position yet */ + for (node = snode->edittree->nodes.first; node; node = node->next) { + if (UNLIKELY(node->anim_ofsx)) { + const float endval = node->anim_init_locx + node->anim_ofsx; + if (IS_EQF(node->locx, endval) == false) { + node->locx = BLI_easing_cubic_ease_in_out(duration, node->anim_init_locx, node->anim_ofsx, + NODE_INSOFS_ANIM_DURATION); + if (node->anim_ofsx < 0) { + CLAMP_MIN(node->locx, endval); + } + else { + CLAMP_MAX(node->locx, endval); + } + redraw = true; + } + } + } + if (redraw) { + ED_region_tag_redraw(CTX_wm_region(C)); + } + + /* end timer + free insert offset data */ if (duration > NODE_INSOFS_ANIM_DURATION) { WM_event_remove_timer(CTX_wm_manager(C), NULL, iofsd->anim_timer); @@ -1653,15 +1677,6 @@ static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const w return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); } - /* handle animation */ - for (node = snode->edittree->nodes.first; node; node = node->next) { - if (node->anim_ofsx) { - node->locx = BLI_easing_cubic_ease_in_out(duration, node->anim_init_locx, node->anim_ofsx, - NODE_INSOFS_ANIM_DURATION); - } - } - ED_region_tag_redraw(CTX_wm_region(C)); - return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 85288aa0011..f2293754608 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -622,7 +622,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, uiLayout *split, *row, *col; bNode *lnode; char label[UI_MAX_NAME_STR]; - int indent = (depth > 1) ? 2 * (depth - 1) : 0; + int i, indent = (depth > 1) ? 2 * (depth - 1) : 0; int dependency_loop; if (input->flag & SOCK_UNAVAIL) @@ -641,7 +641,8 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr); /* indented label */ - memset(label, ' ', indent); + for (i = 0; i < indent; i++) + label[i] = ' '; label[indent] = '\0'; BLI_snprintf(label, UI_MAX_NAME_STR, "%s%s:", label, IFACE_(input->name)); diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 7a5f3867f01..02a53521a46 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -1780,7 +1780,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } draw_custom_bone(scene, v3d, rv3d, pchan->custom, - OB_SOLID, arm->flag, flag, index, bone->length); + OB_SOLID, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan)); } } else { @@ -1871,7 +1871,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, flag |= BONE_DRAW_ACTIVE; draw_custom_bone(scene, v3d, rv3d, pchan->custom, - OB_WIRE, arm->flag, flag, index, bone->length); + OB_WIRE, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan)); glPopMatrix(); } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 5a35e9fcad1..69e354d87c7 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1193,7 +1193,10 @@ static short selectbuffer_ret_hits_5(unsigned int *buffer, const short hits15, c /* we want a select buffer with bones, if there are... */ /* so check three selection levels and compare */ -static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buffer, const int mval[2], bool *p_do_nearest, bool enumerate) +static short mixed_bones_object_selectbuffer( + ViewContext *vc, unsigned int *buffer, const int mval[2], + bool use_cycle, bool enumerate, + bool *r_do_nearest) { rcti rect; int offs; @@ -1204,16 +1207,24 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff View3D *v3d = vc->v3d; /* define if we use solid nearest select or not */ - if (v3d->drawtype > OB_WIRE) { - do_nearest = true; - if (len_manhattan_v2v2_int(mval, last_mval) < 3) { - do_nearest = false; + if (use_cycle) { + if (v3d->drawtype > OB_WIRE) { + do_nearest = true; + if (len_manhattan_v2v2_int(mval, last_mval) < 3) { + do_nearest = false; + } + } + copy_v2_v2_int(last_mval, mval); + } + else { + if (v3d->drawtype > OB_WIRE) { + do_nearest = true; } } - copy_v2_v2_int(last_mval, mval); - if (p_do_nearest) - *p_do_nearest = do_nearest; + if (r_do_nearest) { + *r_do_nearest = do_nearest; + } do_nearest = do_nearest && !enumerate; @@ -1353,7 +1364,7 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2]) view3d_operator_needs_opengl(C); view3d_set_viewcontext(C, &vc); - hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, &do_nearest, false); + hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, false, false, &do_nearest); if (hits > 0) { const bool has_bones = selectbuffer_has_bones(buffer, hits); @@ -1448,7 +1459,7 @@ static bool mouse_select(bContext *C, const int mval[2], /* if objects have posemode set, the bones are in the same selection buffer */ - hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, &do_nearest, enumerate); + hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, true, enumerate, &do_nearest); if (hits > 0) { /* note: bundles are handling in the same way as bones */ diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 9f4d53f1f22..895c8a81044 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -855,21 +855,15 @@ void getConstraintMatrix(TransInfo *t) unit_m3(t->con.pmtx); if (!(t->con.mode & CON_AXIS0)) { - t->con.pmtx[0][0] = - t->con.pmtx[0][1] = - t->con.pmtx[0][2] = 0.0f; + zero_v3(t->con.pmtx[0]); } if (!(t->con.mode & CON_AXIS1)) { - t->con.pmtx[1][0] = - t->con.pmtx[1][1] = - t->con.pmtx[1][2] = 0.0f; + zero_v3(t->con.pmtx[1]); } if (!(t->con.mode & CON_AXIS2)) { - t->con.pmtx[2][0] = - t->con.pmtx[2][1] = - t->con.pmtx[2][2] = 0.0f; + zero_v3(t->con.pmtx[2]); } mul_m3_m3m3(mat, t->con.pmtx, t->con.imtx); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index b8688e5e12a..d574694c70d 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -198,7 +198,8 @@ typedef struct bPoseChannel { short agrp_index; /* index of action-group this bone belongs to (0 = default/no group) */ char constflag; /* for quick detecting which constraints affect this channel */ char selectflag; /* copy of bone flag, so you can work with library armatures, not for runtime use */ - char pad0[6]; + char drawflag; + char pad0[5]; struct Bone *bone; /* set on read file or rebuild pose */ struct bPoseChannel *parent; /* set on read file or rebuild pose */ @@ -212,6 +213,9 @@ typedef struct bPoseChannel { struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. * needed in rare cases for advanced rigs, * since the alternative is highly complicated - campbell */ + float custom_scale; + + char pad1[4]; /* transforms - written in by actions or transform */ float loc[3]; @@ -306,6 +310,14 @@ typedef enum ePchan_IkFlag { BONE_IK_NO_ZDOF_TEMP = (1 << 12) } ePchan_IkFlag; +/* PoseChannel->drawflag */ +typedef enum ePchan_DrawFlag { + PCHAN_DRAW_NO_CUSTOM_BONE_SIZE = (1 << 0), +} ePchan_DrawFlag; + +#define PCHAN_CUSTOM_DRAW_SIZE(pchan) \ + (pchan)->custom_scale * (((pchan)->drawflag & PCHAN_DRAW_NO_CUSTOM_BONE_SIZE) ? 1.0f : (pchan)->bone->length) + /* PoseChannel->rotmode and Object->rotmode */ typedef enum eRotationModes { /* quaternion rotations (default, and for older Blender versions) */ diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 93e5ceaa229..3e41ea4134c 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -746,7 +746,7 @@ static void rna_def_edit_bone(BlenderRNA *brna) prop = RNA_def_property(srna, "roll", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "roll"); - RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 0.1, 2); + RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, 2); RNA_def_property_ui_text(prop, "Roll", "Bone rotation around head-tail axis"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update"); diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index cb577c9c97d..e1e9fc1cf68 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -747,11 +747,12 @@ static int rna_Curve_is_editmode_get(PointerRNA *ptr) #else +static const float tilt_limit = DEG2RADF(21600.0f); + static void rna_def_bpoint(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - const float tilt_limit = DEG2RADF(21600.0f); srna = RNA_def_struct(brna, "SplinePoint", NULL); RNA_def_struct_sdna(srna, "BPoint"); @@ -785,7 +786,7 @@ static void rna_def_bpoint(BlenderRNA *brna) prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "alfa"); RNA_def_property_range(prop, -tilt_limit, tilt_limit); - RNA_def_property_ui_range(prop, -tilt_limit, tilt_limit, 0.1, 3); + RNA_def_property_ui_range(prop, -tilt_limit, tilt_limit, 10, 3); RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); @@ -872,7 +873,8 @@ static void rna_def_beztriple(BlenderRNA *brna) /* Number values */ prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "alfa"); - /*RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/ + RNA_def_property_range(prop, -tilt_limit, tilt_limit); + RNA_def_property_ui_range(prop, -tilt_limit, tilt_limit, 10, 3); RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c index 01feb3cb748..16e0f17eac5 100644 --- a/source/blender/makesrna/intern/rna_fluidsim.c +++ b/source/blender/makesrna/intern/rna_fluidsim.c @@ -343,12 +343,12 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna) prop = RNA_def_property(srna, "start_time", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "animStart"); - RNA_def_property_range(prop, 0, 100); + RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_text(prop, "Start Time", "Simulation time of the first blender frame (in seconds)"); prop = RNA_def_property(srna, "end_time", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "animEnd"); - RNA_def_property_range(prop, 0, 100); + RNA_def_property_range(prop, 0, FLT_MAX); RNA_def_property_ui_text(prop, "End Time", "Simulation time of the last blender frame (in seconds)"); prop = RNA_def_property(srna, "frame_offset", PROP_INT, PROP_NONE); @@ -627,12 +627,12 @@ static void rna_def_fluidsim_control(BlenderRNA *brna) prop = RNA_def_property(srna, "start_time", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "cpsTimeStart"); - RNA_def_property_range(prop, 0.0, 100.0); + RNA_def_property_range(prop, 0.0, FLT_MAX); RNA_def_property_ui_text(prop, "Start Time", "Time when the control particles are activated"); prop = RNA_def_property(srna, "end_time", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "cpsTimeEnd"); - RNA_def_property_range(prop, 0.0, 100.0); + RNA_def_property_range(prop, 0.0, FLT_MAX); RNA_def_property_ui_text(prop, "End Time", "Time when the control particles are deactivated"); prop = RNA_def_property(srna, "attraction_strength", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 1d3f7e42731..9933555f76d 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1493,7 +1493,7 @@ static void rna_def_modifier_decimate(BlenderRNA *brna) prop = RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "angle"); RNA_def_property_range(prop, 0, DEG2RAD(180)); - RNA_def_property_ui_range(prop, 0, DEG2RAD(180), 100, 2); + RNA_def_property_ui_range(prop, 0, DEG2RAD(180), 10, 2); RNA_def_property_ui_text(prop, "Angle Limit", "Only dissolve angles below this (planar only)"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); @@ -2806,7 +2806,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) prop = RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "bevel_angle"); RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f)); - RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 100, 2); + RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 10, 2); RNA_def_property_ui_text(prop, "Angle", "Angle above which to bevel edges"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); @@ -3260,7 +3260,7 @@ static void rna_def_modifier_screw(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); - RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 2, -1); + RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, -1); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_text(prop, "Angle", "Angle of revolution"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 4b66313cdd4..22d0144250e 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -614,7 +614,7 @@ static void rna_def_nlastrip(BlenderRNA *brna) * (minimum should still be > 0 though) if needed... */ RNA_def_property_range(prop, 0.1f, 1000.0f); RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the action range"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + RNA_def_property_update(prop, 0, "rna_NlaStrip_transform_update"); prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "scale"); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index e65023132c9..27ff0a63e75 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -1062,6 +1062,17 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + prop = RNA_def_property(srna, "custom_shape_scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "custom_scale"); + RNA_def_property_range(prop, 0.0f, 1000.0f); + RNA_def_property_ui_text(prop, "Custom Shape Scale", "Adjust the size of the custom shape"); + RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + + prop = RNA_def_property(srna, "use_custom_shape_bone_size", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "drawflag", PCHAN_DRAW_NO_CUSTOM_BONE_SIZE); + RNA_def_property_ui_text(prop, "Use Bone Size", "Scale the custom object by the bone length"); + RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + prop = RNA_def_property(srna, "custom_shape_transform", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "custom_tx"); RNA_def_property_struct_type(prop, "PoseBone"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 845fed15c4d..176c218e378 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2550,7 +2550,7 @@ static void rna_def_statvis(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "overhang_max"); RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f)); - RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 0.001, 3); + RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 10, 3); RNA_def_property_ui_text(prop, "Overhang Max", "Maximum angle to display"); RNA_def_property_update(prop, 0, "rna_EditMesh_update"); @@ -2589,7 +2589,7 @@ static void rna_def_statvis(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "distort_min"); RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f)); - RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 0.001, 3); + RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 10, 3); RNA_def_property_ui_text(prop, "Distort Min", "Minimum angle to display"); RNA_def_property_update(prop, 0, "rna_EditMesh_update"); @@ -2597,7 +2597,7 @@ static void rna_def_statvis(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "distort_max"); RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f)); - RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 0.001, 3); + RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 10, 3); RNA_def_property_ui_text(prop, "Distort Max", "Maximum angle to display"); RNA_def_property_update(prop, 0, "rna_EditMesh_update"); @@ -2606,7 +2606,7 @@ static void rna_def_statvis(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "sharp_min"); RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f)); - RNA_def_property_ui_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f), 0.001, 3); + RNA_def_property_ui_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f), 10, 3); RNA_def_property_ui_text(prop, "Distort Min", "Minimum angle to display"); RNA_def_property_update(prop, 0, "rna_EditMesh_update"); @@ -2614,7 +2614,7 @@ static void rna_def_statvis(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "sharp_max"); RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f)); - RNA_def_property_ui_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f), 0.001, 3); + RNA_def_property_ui_range(prop, -DEG2RADF(180.0f), DEG2RADF(180.0f), 10, 3); RNA_def_property_ui_text(prop, "Distort Max", "Maximum angle to display"); RNA_def_property_update(prop, 0, "rna_EditMesh_update"); } diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 8f45c185798..2192eae9fe6 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -2330,7 +2330,7 @@ static void rna_def_text(StructRNA *srna) RNA_def_property_ui_range(prop, 0.0f, 1000, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); - prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "loc"); RNA_def_property_ui_text(prop, "Location", "Location of the text"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 82600421736..d57ace8d7fe 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -861,7 +861,7 @@ static DerivedMesh *explodeMesh(ExplodeModifierData *emd, BLI_edgehashIterator_free(ehi); /* the final duplicated vertices */ - explode = CDDM_from_template(dm, totdup, 0, totface - delface, 0, 0); + explode = CDDM_from_template_ex(dm, totdup, 0, totface - delface, 0, 0, CD_MASK_DERIVEDMESH | CD_MASK_FACECORNERS); mtface = CustomData_get_layer_named(&explode->faceData, CD_MTFACE, emd->uvname); /*dupvert = CDDM_get_verts(explode);*/ diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index cd86ed24bcb..78be5e558db 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -29,6 +29,11 @@ * BLI_string_utf8() for unicode conversion. */ +/* TODO, resolve linking errors on win32 */ +#ifndef _WIN32 +/* needed for Py3.6+ to access Py_PyThreadState_Current */ +#define Py_BUILD_CORE +#endif #include <Python.h> #include <frameobject.h> @@ -666,7 +671,8 @@ void PyC_SetHomePath(const char *py_path_bundle) bool PyC_IsInterpreterActive(void) { - return (PyThreadState_GET() != NULL); + /* expanded PyThreadState_GET which won't throw an exception */ + return (((PyThreadState *)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL); } /* Would be nice if python had this built in diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 2a679f0f0d0..fd56c47c309 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -207,6 +207,10 @@ void RE_InitRenderCB(struct Render *re); void RE_FreeRender(struct Render *re); /* only called on exit */ void RE_FreeAllRender(void); +/* Free memory used by persistent data. + * Invoked when loading new file. + */ +void RE_FreeAllPersistentData(void); /* only call on file load */ void RE_FreeAllRenderResults(void); /* for external render engines that can keep persistent data */ diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index 0223f76f869..dcc33b99742 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -612,7 +612,7 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, int col = cell_index % polys_per_grid_side; /* S is the vertex whose grid we are examining */ - S = loc_cage_poly_offs / (polys_per_grid_side * polys_per_grid_side); + S = poly_index / (1 << (2 * (lvl - 1))) - grid_offset[cage_face_index]; /* get offset of grid data for original cage face */ g_index = grid_offset[cage_face_index]; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 46fb0603038..ad0856497c3 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -533,6 +533,17 @@ void RE_FreeAllRender(void) #endif } +void RE_FreeAllPersistentData(void) +{ + Render *re; + for (re = RenderGlobal.renderlist.first; re != NULL; re = re->next) { + if ((re->r.mode & R_PERSISTENT_DATA) != 0 && re->engine != NULL) { + RE_engine_free(re->engine); + re->engine = NULL; + } + } +} + /* on file load, free all re */ void RE_FreeAllRenderResults(void) { @@ -3506,6 +3517,11 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri get_videos_dimensions(re, &rd, &width, &height); mh = BKE_movie_handle_get(scene->r.im_format.imtype); + if (mh == NULL) { + BKE_report(re->reports, RPT_ERROR, "Movie format unsupported"); + return; + } + re->movie_ctx_arr = MEM_mallocN(sizeof(void *) * totvideos, "Movies' Context"); for (i = 0; i < totvideos; i++) { diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 70a8fdf3ba3..900312ee984 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -736,6 +736,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con //shi.sample= 0; // memset above, so don't need this shi.xs= origshi->xs; shi.ys= origshi->ys; + shi.do_manage= origshi->do_manage; shi.lay= origshi->lay; shi.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */ shi.combinedflag= 0xFFFFFF; /* ray trace does all options */ @@ -1622,6 +1623,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int shi.xs= origshi->xs; shi.ys= origshi->ys; + shi.do_manage= origshi->do_manage; shi.lay= origshi->lay; shi.nodes= origshi->nodes; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 894ade42a1f..910ea16607e 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -1971,9 +1971,9 @@ void add_halo_flare(Render *re) rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, re->viewname); - if (rl==NULL || rect) - return; - + if (rect==NULL) + continue; + mode= R.r.mode; R.r.mode &= ~R_PANORAMA; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index d271592af5f..7a9b2d0903e 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1377,8 +1377,8 @@ ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, obi->lay= lay; /* Fill particle info */ - if (obi->psysindex >= 0) { - int psysindex = 0; + if (obi->psysindex > 0) { + int psysindex = 1; int index; ParticleSystem *psys; if (obi->par) { diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 39dfa48d3f1..91f9723897c 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1815,7 +1815,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) shr->combined[1]= shi->g; shr->combined[2]= shi->b; shr->alpha= shi->alpha; - return; + goto finally_shadeless; } if ( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { /* vertexcolor light */ @@ -2006,7 +2006,11 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) add_v3_v3(shr->combined, shr->emit); if (shi->combinedflag & SCE_PASS_SPEC) add_v3_v3(shr->combined, shr->spec); - + + + /* Last section of this function applies to shadeless colors too */ +finally_shadeless: + /* modulate by the object color */ if ((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) { if (!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) { diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 6927e2dbc14..d08c6c59a7f 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -106,6 +106,9 @@ #include "GPU_draw.h" +/* only to report a missing engine */ +#include "RE_engine.h" + #ifdef WITH_PYTHON #include "BPY_extern.h" #endif @@ -401,6 +404,89 @@ void WM_file_autoexec_init(const char *filepath) } } +void wm_file_read_report(bContext *C) +{ + ReportList *reports = NULL; + Scene *sce; + + for (sce = G.main->scene.first; sce; sce = sce->id.next) { + if (sce->r.engine[0] && + BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL) + { + if (reports == NULL) { + reports = CTX_wm_reports(C); + } + + BKE_reportf(reports, RPT_ERROR, + "Engine '%s' not available for scene '%s' " + "(an addon may need to be installed or enabled)", + sce->r.engine, sce->id.name + 2); + } + } + + if (reports) { + if (!G.background) { + WM_report_banner_show(C); + } + } +} + +/** + * Logic shared between #WM_file_read & #wm_homefile_read, + * updates to make after reading a file. + */ +static void wm_file_read_post(bContext *C, bool is_startup_file) +{ + bool addons_loaded = false; + CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); + + ED_editors_init(C); + DAG_on_visible_update(CTX_data_main(C), true); + +#ifdef WITH_PYTHON + if (is_startup_file) { + /* possible python hasn't been initialized */ + if (CTX_py_init_get(C)) { + /* sync addons, these may have changed from the defaults */ + BPY_string_exec(C, "__import__('addon_utils').reset_all()"); + + BPY_python_reset(C); + addons_loaded = true; + } + } + else { + /* run any texts that were loaded in and flagged as modules */ + BPY_python_reset(C); + addons_loaded = true; + } +#endif /* WITH_PYTHON */ + + WM_operatortype_last_properties_clear_all(); + + /* important to do before NULL'ing the context */ + BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE); + BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); + + WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); + + /* report any errors. + * currently disabled if addons aren't yet loaded */ + if (addons_loaded) { + wm_file_read_report(C); + } + + if (!G.background) { + /* in background mode this makes it hard to load + * a blend file and do anything since the screen + * won't be set to a valid value again */ + CTX_wm_window_set(C, NULL); /* exits queues */ + } + +// undo_editmode_clear(); + BKE_undo_reset(); + BKE_undo_write(C, "original"); /* save current state */ +} + bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) { /* assume automated tasks with background, don't write recent file list */ @@ -465,53 +551,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) } } - - WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); -// refresh_interface_font(); - - CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); - - ED_editors_init(C); - DAG_on_visible_update(CTX_data_main(C), true); - -#ifdef WITH_PYTHON - /* run any texts that were loaded in and flagged as modules */ - BPY_python_reset(C); -#endif - - WM_operatortype_last_properties_clear_all(); - - /* important to do before NULL'ing the context */ - BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE); - BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); - - if (!G.background) { - /* in background mode this makes it hard to load - * a blend file and do anything since the screen - * won't be set to a valid value again */ - CTX_wm_window_set(C, NULL); /* exits queues */ - } - -#if 0 - /* gives popups on windows but not linux, bug in report API - * but disable for now to stop users getting annoyed */ - /* TODO, make this show in header info window */ - { - Scene *sce; - for (sce = G.main->scene.first; sce; sce = sce->id.next) { - if (sce->r.engine[0] && - BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL) - { - BKE_reportf(reports, RPT_ERROR, "Engine '%s' not available for scene '%s' " - "(an addon may need to be installed or enabled)", - sce->r.engine, sce->id.name + 2); - } - } - } -#endif - - BKE_undo_reset(); - BKE_undo_write(C, "original"); /* save current state */ + wm_file_read_post(C, false); success = true; } @@ -673,36 +713,7 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c G.save_over = 0; // start with save preference untitled.blend G.fileflags &= ~G_FILE_AUTOPLAY; /* disable autoplay in startup.blend... */ -// refresh_interface_font(); - -// undo_editmode_clear(); - BKE_undo_reset(); - BKE_undo_write(C, "original"); /* save current state */ - - ED_editors_init(C); - DAG_on_visible_update(CTX_data_main(C), true); - -#ifdef WITH_PYTHON - if (CTX_py_init_get(C)) { - /* sync addons, these may have changed from the defaults */ - BPY_string_exec(C, "__import__('addon_utils').reset_all()"); - - BPY_python_reset(C); - } -#endif - - WM_operatortype_last_properties_clear_all(); - - /* important to do before NULL'ing the context */ - BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE); - BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); - - WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); - - /* in background mode the scene will stay NULL */ - if (!G.background) { - CTX_wm_window_set(C, NULL); /* exits queues */ - } + wm_file_read_post(C, true); return true; } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 8cf9b2c02c7..fec2671edba 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -176,6 +176,10 @@ void WM_init(bContext *C, int argc, const char **argv) ED_spacedropwidgets_init(); + /* reports cant be initialized before the wm, + * but keep before file reading, since that may report errors */ + wm_init_reports(C); + /* get the default database, plus a wm */ wm_homefile_read(C, NULL, G.factory_startup, NULL); @@ -231,8 +235,6 @@ void WM_init(bContext *C, int argc, const char **argv) if (!G.background && !wm_start_with_console) GHOST_toggleConsole(3); - wm_init_reports(C); /* reports cant be initialized before the wm */ - clear_matcopybuf(); ED_render_clear_mtex_copybuf(); @@ -261,13 +263,24 @@ void WM_init(bContext *C, int argc, const char **argv) /* that prevents loading both the kept session, and the file on the command line */ } else { + /* note, logic here is from wm_file_read_post, + * call functions that depend on Python being initialized. */ + /* normally 'wm_homefile_read' will do this, * however python is not initialized when called from this function. * * unlikely any handlers are set but its possible, * note that recovering the last session does its own callbacks. */ + CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); + BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); + + wm_file_read_report(C); + + if (!G.background) { + CTX_wm_window_set(C, NULL); + } } } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index a03f2c22055..0b0cedf5825 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1017,7 +1017,6 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr #if defined(__APPLE__) || defined(WIN32) /* OSX and Win32 don't return to the mainloop while resize */ - wm_event_do_handlers(C); wm_event_do_notifiers(C); wm_draw_update(C); @@ -1278,7 +1277,7 @@ void WM_event_timer_sleep(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *t wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep) { wmTimer *wt = MEM_callocN(sizeof(wmTimer), "window timer"); - + wt->event_type = event_type; wt->ltime = PIL_check_seconds_timer(); wt->ntime = wt->ltime + timestep; diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h index 467926aa770..4b35f662a99 100644 --- a/source/blender/windowmanager/wm_files.h +++ b/source/blender/windowmanager/wm_files.h @@ -38,6 +38,7 @@ int wm_homefile_read_exec(struct bContext *C, struct wmOperator *op); int wm_homefile_read(struct bContext *C, struct ReportList *reports, bool from_memory, const char *filepath); int wm_homefile_write_exec(struct bContext *C, struct wmOperator *op); int wm_userpref_write_exec(struct bContext *C, struct wmOperator *op); +void wm_file_read_report(bContext *C); #endif /* __WM_FILES_H__ */ diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index f5257436291..f0abab6a82b 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -640,6 +640,7 @@ void RE_engine_frame_set(struct RenderEngine *engine, int frame, float subframe) void RE_FreePersistentData(void) RET_NONE void RE_sample_point_density(struct Scene *scene, struct PointDensity *pd, int resolution, float *values) RET_NONE; void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE +void RE_FreeAllPersistentData(void) RET_NONE /* python */ struct wmOperatorType *WM_operatortype_find(const char *idname, bool quiet) RET_NULL diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 8ed9b51f736..fd2176e64d7 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -73,6 +73,16 @@ if(USE_EXPERIMENTAL_TESTS) ) endif() +# ------------------------------------------------------------------------------ +# PY API TESTS +add_test(script_pyapi_bpy_path ${TEST_BLENDER_EXE} + --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_path.py +) + +add_test(script_pyapi_bpy_utils_units ${TEST_BLENDER_EXE} + --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_utils_units.py +) + # test running mathutils testing script add_test(script_pyapi_mathutils ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_mathutils.py diff --git a/tests/python/bl_load_py_modules.py b/tests/python/bl_load_py_modules.py index 5cd21058c99..4256cba0933 100644 --- a/tests/python/bl_load_py_modules.py +++ b/tests/python/bl_load_py_modules.py @@ -38,6 +38,9 @@ BLACKLIST = { 'io_import_dxf', # Because of cydxfentity.so dependency } +if not bpy.app.build_options.freestyle: + BLACKLIST.add("render_freestyle_svg") + BLACKLIST_DIRS = ( os.path.join(bpy.utils.resource_path('USER'), "scripts"), ) + tuple(addon_utils.paths()[1:]) @@ -75,8 +78,11 @@ def load_addons(): for mod in modules: mod_name = mod.__name__ + if mod_name in BLACKLIST: + continue addon_utils.enable(mod_name, default_set=True) - assert(mod_name in addons) + if not (mod_name in addons): + raise Exception("'addon_utils.enable(%r)' call failed" % mod_name) def load_modules(): @@ -157,7 +163,8 @@ def load_modules(): ignore_paths = [ os.sep + "presets" + os.sep, os.sep + "templates" + os.sep, - ] + [(os.sep + f + os.sep) for f in BLACKLIST] + ] + ([(os.sep + f + os.sep) for f in BLACKLIST] + + [(os.sep + f + ".py") for f in BLACKLIST]) for f in source_files: ok = False diff --git a/tests/python/bl_mesh_modifiers.py b/tests/python/bl_mesh_modifiers.py index 2db38895f9b..0121be29dd6 100644 --- a/tests/python/bl_mesh_modifiers.py +++ b/tests/python/bl_mesh_modifiers.py @@ -197,8 +197,9 @@ def defaults_object(obj): obj.show_wire = True if obj.type == 'MESH': + obj.show_all_edges = True + mesh = obj.data - mesh.show_all_edges = True mesh.show_normal_vertex = True diff --git a/tests/python/bl_bpy_path.py b/tests/python/bl_pyapi_bpy_path.py index 5c4ae91a5df..2d6019fbb07 100644 --- a/tests/python/bl_bpy_path.py +++ b/tests/python/bl_pyapi_bpy_path.py @@ -1,6 +1,6 @@ # Apache License, Version 2.0 -# ./blender.bin --background -noaudio --python tests/python/bl_bpy_path.py -- --verbose +# ./blender.bin --background -noaudio --python tests/python/bl_pyapi_bpy_path.py -- --verbose import unittest diff --git a/tests/python/bl_pyapi_units.py b/tests/python/bl_pyapi_bpy_utils_units.py index 128cc100b25..f40dab4b5eb 100644 --- a/tests/python/bl_pyapi_units.py +++ b/tests/python/bl_pyapi_bpy_utils_units.py @@ -1,6 +1,6 @@ # Apache License, Version 2.0 -# ./blender.bin --background -noaudio --python tests/python/bl_pyapi_units.py -- --verbose +# ./blender.bin --background -noaudio --python tests/python/bl_pyapi_bpy_utils_units.py -- --verbose import unittest from bpy.utils import units |