diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 9600340a1f3..9a86cee6546 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -63,7 +63,7 @@ static PyObject *create_func(PyObject *self, PyObject *args) BL::RenderEngine engine(engineptr); PointerRNA userprefptr; - RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyuserpref), &userprefptr); + RNA_pointer_create(NULL, &RNA_UserPreferences, (void*)PyLong_AsVoidPtr(pyuserpref), &userprefptr); BL::UserPreferences userpref(userprefptr); PointerRNA dataptr; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index fdce4b16b57..ecdc631e39a 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -102,11 +102,18 @@ void BlenderSession::create_session() /* create sync */ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU); - /* for final render we will do sync per render layer */ if(b_v3d) { + /* full data sync */ sync->sync_data(b_v3d, b_engine.camera_override()); sync->sync_view(b_v3d, b_rv3d, width, height); } + else { + /* for final render we will do full data sync per render layer, only + * do some basic syncing here, no objects or materials for speed */ + sync->sync_render_layers(b_v3d, NULL); + sync->sync_integrator(); + sync->sync_camera(b_render, b_engine.camera_override(), width, height); + } /* set buffer parameters */ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height); @@ -370,8 +377,8 @@ void BlenderSession::render() scene->integrator->tag_update(scene); /* update scene */ - sync->sync_data(b_v3d, b_engine.camera_override(), b_rlay_name.c_str()); sync->sync_camera(b_render, b_engine.camera_override(), width, height); + sync->sync_data(b_v3d, b_engine.camera_override(), b_rlay_name.c_str()); /* update number of samples per layer */ int samples = sync->get_layer_samples(); diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 5b63042a682..ed1f2b9d70f 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -56,6 +56,8 @@ public: /* sync */ bool sync_recalc(); void sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const char *layer = 0); + void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer); + void sync_integrator(); void sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height); void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height); int get_layer_samples() { return render_layer.samples; } @@ -74,10 +76,8 @@ private: void sync_objects(BL::SpaceView3D b_v3d, int motion = 0); void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override); void sync_film(); - void sync_integrator(); void sync_view(); void sync_world(bool update_all); - void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer); void sync_shaders(); void sync_curve_settings(); diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index f87f5dec741..8b4466863e0 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -129,9 +129,20 @@ if(WITH_CYCLES_CUDA_BINARIES) foreach(arch ${CYCLES_CUDA_BINARIES_ARCH}) set(cuda_cubin kernel_${arch}.cubin) + if(${arch} MATCHES "sm_1[0-9]") + # sm_1x + set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0") + elseif(${arch} MATCHES "sm_2[0-9]") + # sm_2x + set(cuda_arch_flags "--maxrregcount=24") + else() + # sm_3x + set(cuda_arch_flags "--maxrregcount=32") + endif() + add_custom_command( OUTPUT ${cuda_cubin} - COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" --maxrregcount=24 --opencc-options -OPT:Olimit=0 -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC + COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC DEPENDS ${cuda_sources}) delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib) diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h index 5ea44cd0cad..15d2151228f 100644 --- a/intern/cycles/kernel/kernel_jitter.h +++ b/intern/cycles/kernel/kernel_jitter.h @@ -146,7 +146,7 @@ __device_noinline float cmj_sample_1D(int s, int N, int p) return (x + jx)*invN; } -__device_noinline float2 cmj_sample_2D(int s, int N, int p) +__device_noinline void cmj_sample_2D(int s, int N, int p, float *fx, float *fy) { int m = float_to_int(sqrtf(N)); int n = (N + m - 1)/m; @@ -173,7 +173,8 @@ __device_noinline float2 cmj_sample_2D(int s, int N, int p) float jx = cmj_randfloat(s, p * 0x967a889b); float jy = cmj_randfloat(s, p * 0x368cc8b7); - return make_float2((sx + (sy + jx)*invn)*invm, (s + jy)*invN); + *fx = (sx + (sy + jx)*invn)*invm; + *fy = (s + jy)*invN; } #endif diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index f58f83e2f82..b895d1fcf52 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -409,9 +409,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { /* todo: solve correlation */ - float2 bsdf_uv = path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); float ao_factor = kernel_data.background.ao_factor; float3 ao_N; @@ -450,9 +449,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, #else float light_o = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_F); #endif - float2 light_uv = path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_U); - float light_u = light_uv.x; - float light_v = light_uv.y; + float light_u, light_v; + path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); Ray light_ray; BsdfEval L_light; @@ -484,9 +482,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, BsdfEval bsdf_eval; float3 bsdf_omega_in; differential3 bsdf_domega_in; - float2 bsdf_uv = path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval, @@ -653,10 +650,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - /* todo: solve correlation */ - float2 bsdf_uv = path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); float ao_factor = kernel_data.background.ao_factor; float3 ao_N; @@ -695,9 +690,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray #else float light_o = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_F); #endif - float2 light_uv = path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_U); - float light_u = light_uv.x; - float light_v = light_uv.y; + float light_u, light_v; + path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); Ray light_ray; BsdfEval L_light; @@ -730,9 +724,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray BsdfEval bsdf_eval; float3 bsdf_omega_in; differential3 bsdf_domega_in; - float2 bsdf_uv = path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval, @@ -784,10 +777,8 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N); for(int j = 0; j < num_samples; j++) { - /* todo: solve correlation */ - float2 bsdf_uv = path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); float3 ao_D; float ao_pdf; @@ -836,9 +827,8 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R num_samples_inv *= 0.5f; for(int j = 0; j < num_samples; j++) { - float2 light_uv = path_rng_2D(kg, &lamp_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U); - float light_u = light_uv.x; - float light_v = light_uv.y; + float light_u, light_v; + path_rng_2D(kg, &lamp_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ @@ -862,9 +852,8 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R for(int j = 0; j < num_samples; j++) { float light_t = path_rng_1D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT); - float2 light_uv = path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U); - float light_u = light_uv.x; - float light_v = light_uv.y; + float light_u, light_v; + path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); /* only sample triangle lights */ if(kernel_data.integrator.num_all_lights) @@ -913,9 +902,8 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R BsdfEval bsdf_eval; float3 bsdf_omega_in; differential3 bsdf_domega_in; - float2 bsdf_uv = path_rng_2D(kg, &bsdf_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, &bsdf_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, @@ -1162,11 +1150,8 @@ __device void kernel_path_trace(KernelGlobals *kg, float lens_u = 0.0f, lens_v = 0.0f; - if(kernel_data.cam.aperturesize > 0.0f) { - float2 lens_uv = path_rng_2D(kg, &rng, sample, num_samples, PRNG_LENS_U); - lens_u = lens_uv.x; - lens_v = lens_uv.y; - } + if(kernel_data.cam.aperturesize > 0.0f) + path_rng_2D(kg, &rng, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v); float time = 0.0f; diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index b5f824d5cce..20fc1fe2253 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -102,8 +102,16 @@ __device uint sobol_lookup(const uint m, const uint frame, const uint ex, const return index; } -__device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dimension) +__device_inline float path_rng_1D(KernelGlobals *kg, RNG *rng, int sample, int num_samples, int dimension) { +#ifdef __CMJ__ + if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) { + /* correlated multi-jittered */ + int p = *rng + dimension; + return cmj_sample_1D(sample, num_samples, p); + } +#endif + #ifdef __SOBOL_FULL_SCREEN__ uint result = sobol_dimension(kg, *rng, dimension); float r = (float)result * (1.0f/(float)0xFFFFFFFF); @@ -117,41 +125,27 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dime float shift; if(dimension & 1) - shift = (*rng >> 16)*(1.0f/(float)0xFFFF); + shift = (*rng >> 16)/((float)0xFFFF); else - shift = (*rng & 0xFFFF)*(1.0f/(float)0xFFFF); + shift = (*rng & 0xFFFF)/((float)0xFFFF); return r + shift - floorf(r + shift); #endif } -__device_inline float path_rng_1D(KernelGlobals *kg, RNG *rng, int sample, int num_samples, int dimension) +__device_inline void path_rng_2D(KernelGlobals *kg, RNG *rng, int sample, int num_samples, int dimension, float *fx, float *fy) { #ifdef __CMJ__ if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) { /* correlated multi-jittered */ int p = *rng + dimension; - return cmj_sample_1D(sample, num_samples, p); + cmj_sample_2D(sample, num_samples, p, fx, fy); } #endif /* sobol */ - return path_rng(kg, rng, sample, dimension); -} - -__device_inline float2 path_rng_2D(KernelGlobals *kg, RNG *rng, int sample, int num_samples, int dimension) -{ -#ifdef __CMJ__ - if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) { - /* correlated multi-jittered */ - int p = *rng + dimension; - return cmj_sample_2D(sample, num_samples, p); - } -#endif - - /* sobol */ - return make_float2(path_rng(kg, rng, sample, dimension), - path_rng(kg, rng, sample, dimension + 1)); + *fx = path_rng_1D(kg, rng, sample, num_samples, dimension); + *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1); } __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, int num_samples, RNG *rng, int x, int y, float *fx, float *fy) @@ -184,10 +178,7 @@ __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, *fy = 0.5f; } else { - float2 fxy = path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U); - - *fx = fxy.x; - *fy = fxy.y; + path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U, fx, fy); } #endif } @@ -202,21 +193,20 @@ __device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng) /* Linear Congruential Generator */ __device float path_rng(KernelGlobals *kg, RNG& rng, int sample, int dimension) +{ +} + +__device_inline float path_rng_1D(KernelGlobals *kg, RNG& rng, int sample, int num_samples, int dimension) { /* implicit mod 2^32 */ rng = (1103515245*(rng) + 12345); return (float)rng * (1.0f/(float)0xFFFFFFFF); } -__device_inline float path_rng_1D(KernelGlobals *kg, RNG& rng, int sample, int num_samples, int dimension) +__device_inline void path_rng_2D(KernelGlobals *kg, RNG& rng, int sample, int num_samples, int dimension, float *fx, float *fy) { - return path_rng(kg, rng, sample, dimension); -} - -__device_inline float2 path_rng_2D(KernelGlobals *kg, RNG& rng, int sample, int num_samples, int dimension) -{ - return make_float2(path_rng(kg, rng, sample, dimension), - path_rng(kg, rng, sample, dimension + 1)); + *fx = path_rng_1D(kg, rng, sample, num_samples, dimension); + *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1); } __device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, int num_samples, RNG *rng, int x, int y, float *fx, float *fy) @@ -231,10 +221,7 @@ __device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sam *fy = 0.5f; } else { - float2 fxy = path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U); - - *fx = fxy.x; - *fy = fxy.y; + path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U, fx, fy); } } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index bec45e23f7a..74033d5c2fa 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2969,7 +2969,7 @@ void WavelengthNode::compile(SVMCompiler& compiler) compiler.stack_assign(wavelength_in); compiler.stack_assign(color_out); - compiler.add_node(NODE_WAVELENGTH, wavelength_in->stack_offset, color_out->stack_offset, NULL); + compiler.add_node(NODE_WAVELENGTH, wavelength_in->stack_offset, color_out->stack_offset); } void WavelengthNode::compile(OSLCompiler& compiler) diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index b78105dedb5..ec3891e8d76 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -482,8 +482,9 @@ def preset_find(name, preset_path, display_name=False, ext=".py"): return filepath -def keyconfig_set(filepath): +def keyconfig_set(filepath, report=None): from os.path import basename, splitext + from itertools import chain if _bpy.app.debug_python: print("loading preset:", filepath) @@ -496,25 +497,36 @@ def keyconfig_set(filepath): keyfile = open(filepath) exec(compile(keyfile.read(), filepath, "exec"), {"__file__": filepath}) keyfile.close() + error_msg = "" except: import traceback - traceback.print_exc() + error_msg = traceback.format_exc() - kc_new = [kc for kc in keyconfigs if kc not in keyconfigs_old][0] + if error_msg: + if report is not None: + report({'ERROR'}, error_msg) + print(error_msg) - kc_new.name = "" + kc_new = next(chain(iter(kc for kc in keyconfigs if kc not in keyconfigs_old), (None,))) + if kc_new is None: + if report is not None: + report({'ERROR'}, "Failed to load keymap %r" % filepath) + return False + else: + kc_new.name = "" - # remove duplicates - name = splitext(basename(filepath))[0] - while True: - kc_dupe = keyconfigs.get(name) - if kc_dupe: - keyconfigs.remove(kc_dupe) - else: - break + # remove duplicates + name = splitext(basename(filepath))[0] + while True: + kc_dupe = keyconfigs.get(name) + if kc_dupe: + keyconfigs.remove(kc_dupe) + else: + break - kc_new.name = name - keyconfigs.active = kc_new + kc_new.name = name + keyconfigs.active = kc_new + return True def user_resource(resource_type, path="", create=False): diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index a2a8c991259..9cd9131ec4b 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1199,9 +1199,10 @@ class WM_OT_keyconfig_activate(Operator): ) def execute(self, context): - bpy.utils.keyconfig_set(self.filepath) - return {'FINISHED'} - + if bpy.utils.keyconfig_set(self.filepath, report=self.report): + return {'FINISHED'} + else: + return {'CANCELLED'} class WM_OT_appconfig_default(Operator): bl_idname = "wm.appconfig_default" @@ -1386,9 +1387,10 @@ class WM_OT_keyconfig_import(Operator): return {'CANCELLED'} # sneaky way to check we're actually running the code. - bpy.utils.keyconfig_set(path) - - return {'FINISHED'} + if bpy.utils.keyconfig_set(path, report=self.report): + return {'FINISHED'} + else: + return {'CANCELLED'} def invoke(self, context, event): wm = context.window_manager diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 7487aaf420d..5d476c01b08 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -67,14 +67,13 @@ class INFO_HT_header(Header): if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False: layout.operator_context = 'EXEC_DEFAULT' - row.label("Script failed to auto-run", icon='ERROR') + row.label("Auto-run disabled: %s" % bpy.app.autoexec_fail_message, icon='ERROR') if bpy.data.is_saved: props = row.operator("wm.open_mainfile", icon='SCREEN_BACK', text="Reload Trusted") props.filepath = bpy.data.filepath props.use_scripts = True - row.operator("script.autoexec_warn_clear", icon='CANCEL') - row.label("Skipping: (%s)" % bpy.app.autoexec_fail_message) + row.operator("script.autoexec_warn_clear", text="Ignore") return row.operator("wm.splash", text="", icon='BLENDER', emboss=False) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 7bb188d5ff6..3054849999c 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -221,7 +221,8 @@ void BKE_mesh_calc_normals_mapping_ex( void BKE_mesh_calc_normals_poly( struct MVert *mverts, int numVerts, struct MLoop *mloop, struct MPoly *mpolys, - int numLoops, int numPolys, float (*polyNors_r)[3]); + int numLoops, int numPolys, float (*polyNors_r)[3], + const bool only_face_normals); void BKE_mesh_calc_normals(struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index e466964c73f..6b9392a4169 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -371,11 +371,12 @@ typedef struct CDMaskLink { * evaluation, assuming the data indicated by dataMask is required at the * end of the stack. */ -struct CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, +struct CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, struct Object *ob, struct ModifierData *md, CustomDataMask dataMask, - int required_mode); + int required_mode, + ModifierData *previewmd, CustomDataMask previewmask); struct ModifierData *modifiers_getLastPreview(struct Scene *scene, struct ModifierData *md, int required_mode); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 55f68fcb8bd..b43747ab33a 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -917,6 +917,11 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria #define CMP_SCALE_RENDERSIZE_FRAME_ASPECT (1 << 0) #define CMP_SCALE_RENDERSIZE_FRAME_CROP (1 << 1) +/* track position node, in custom1 */ +#define CMP_TRACKPOS_ABSOLUTE 0 +#define CMP_TRACKPOS_RELATIVE_START 1 +#define CMP_TRACKPOS_RELATIVE_FRAME 2 +#define CMP_TRACKPOS_ABSOLUTE_FRAME 3 /* API */ struct CompBuf; @@ -925,7 +930,7 @@ void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int r void ntreeCompositTagRender(struct Scene *sce); int ntreeCompositTagAnimated(struct bNodeTree *ntree); void ntreeCompositTagGenerators(struct bNodeTree *ntree); -void ntreeCompositForceHidden(struct bNodeTree *ntree, struct Scene *scene); +void ntreeCompositForceHidden(struct bNodeTree *ntree); void ntreeCompositClearTags(struct bNodeTree *ntree); struct bNodeSocket *ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree, struct bNode *node, diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index d8c761cd1b4..84bca0bd3ba 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -204,10 +204,10 @@ void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ListBase *t /* **** 2D stabilization **** */ void BKE_tracking_stabilization_data_get(struct MovieTracking *tracking, int framenr, int width, int height, - float loc[2], float *scale, float *angle); + float translation[2], float *scale, float *angle); struct ImBuf *BKE_tracking_stabilize_frame(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, - float loc[2], float *scale, float *angle); -void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2], + float translation[2], float *scale, float *angle); +void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float translation[2], float scale, float angle, float mat[4][4]); /* Dopesheet */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index fc226288f04..6a21f33ac15 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1482,7 +1482,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos ModifierData *firstmd, *md, *previewmd = NULL; CDMaskLink *datamasks, *curr; /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */ - CustomDataMask mask, nextmask, append_mask = CD_MASK_ORIGINDEX; + CustomDataMask mask, nextmask, previewmask = 0, append_mask = CD_MASK_ORIGINDEX; float (*deformedVerts)[3] = NULL; DerivedMesh *dm = NULL, *orcodm, *clothorcodm, *finaldm; int numVerts = me->totvert; @@ -1532,17 +1532,24 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if (useRenderParams) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; - datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); - curr = datamasks; - if (do_mod_wmcol || do_mod_mcol) { /* Find the last active modifier generating a preview, or NULL if none. */ /* XXX Currently, DPaint modifier just ignores this. * Needs a stupid hack... * The whole "modifier preview" thing has to be (re?)designed, anyway! */ previewmd = modifiers_getLastPreview(scene, md, required_mode); + + /* even if the modifier doesn't need the data, to make a preview it may */ + if (previewmd) { + if (do_mod_wmcol) { + previewmask = CD_MASK_MDEFORMVERT; + } + } } + datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, previewmask); + curr = datamasks; + if (deform_r) *deform_r = NULL; *final_r = NULL; @@ -2028,7 +2035,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D dm = NULL; md = modifiers_getVirtualModifierList(ob); - datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); + datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, NULL, 0); curr = datamasks; for (i = 0; md; i++, md = md->next, curr = curr->next) { diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index af0dadeccab..64d6ca6666e 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -2291,7 +2291,7 @@ void CDDM_calc_normals(DerivedMesh *dm) } BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), - dm->numLoopData, dm->numPolyData, poly_nors); + dm->numLoopData, dm->numPolyData, poly_nors, false); cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } @@ -2306,7 +2306,7 @@ void CDDM_calc_normals(DerivedMesh *dm) cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData); BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), - dm->numLoopData, dm->numPolyData, NULL); + dm->numLoopData, dm->numPolyData, NULL, false); cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 1f381a1a2c2..903b032e080 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -172,9 +172,6 @@ void BKE_lamp_make_local(Lamp *la) if (la->id.lib == NULL) return; if (la->id.us == 1) { id_clear_lib_data(bmain, &la->id); - /* nodetree uses same lib */ - if (la->nodetree) - la->nodetree->id.lib = NULL; return; } @@ -189,9 +186,6 @@ void BKE_lamp_make_local(Lamp *la) if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &la->id); - /* nodetree uses same lib */ - if (la->nodetree) - la->nodetree->id.lib = NULL; } else if (is_local && is_lib) { Lamp *la_new = BKE_lamp_copy(la); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index db4706e3c6c..c1715ada7bd 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1428,11 +1428,26 @@ bool new_id(ListBase *lb, ID *id, const char *tname) * don't have other library users. */ void id_clear_lib_data(Main *bmain, ID *id) { + bNodeTree *ntree = NULL; + BKE_id_lib_local_paths(bmain, id->lib, id); id->lib = NULL; id->flag = LIB_LOCAL; new_id(which_libbase(bmain, GS(id->name)), id, NULL); + + /* internal bNodeTree blocks inside ID types below + * also stores id->lib, make sure this stays in sync. + */ + switch (GS(id->name)) { + case ID_SCE: ntree = ((Scene *)id)->nodetree; break; + case ID_MA: ntree = ((Material *)id)->nodetree; break; + case ID_LA: ntree = ((Lamp *)id)->nodetree; break; + case ID_WO: ntree = ((World *)id)->nodetree; break; + case ID_TE: ntree = ((Tex *)id)->nodetree; break; + } + if (ntree) + ntree->id.lib = NULL; } /* next to indirect usage in read/writefile also in editobject.c scene.c */ diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 87fb64c0761..c8cd65e9477 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -308,9 +308,6 @@ void BKE_material_make_local(Material *ma) if (ma->id.us == 1) { id_clear_lib_data(bmain, &ma->id); extern_local_material(ma); - /* nodetree uses same lib */ - if (ma->nodetree) - ma->nodetree->id.lib = NULL; return; } @@ -373,9 +370,6 @@ void BKE_material_make_local(Material *ma) if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &ma->id); extern_local_material(ma); - /* nodetree uses same lib */ - if (ma->nodetree) - ma->nodetree->id.lib = NULL; } /* Both user and local, so copy. */ else if (is_local && is_lib) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 2eb318c316f..d02884f1a7b 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1907,7 +1907,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts, if (only_face_normals == FALSE) { /* vertex normals are optional, they require some extra calculations, * so make them optional */ - BKE_mesh_calc_normals_poly(mverts, numVerts, mloop, mpolys, numLoops, numPolys, pnors); + BKE_mesh_calc_normals_poly(mverts, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false); } else { /* only calc poly normals */ @@ -1994,13 +1994,24 @@ static void mesh_calc_normals_poly_accum(MPoly *mp, MLoop *ml, } void BKE_mesh_calc_normals_poly(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpolys, - int UNUSED(numLoops), int numPolys, float (*r_polynors)[3]) + int UNUSED(numLoops), int numPolys, float (*r_polynors)[3], + const bool only_face_normals) { float (*pnors)[3] = r_polynors; float (*tnorms)[3]; int i; MPoly *mp; + if (only_face_normals) { + BLI_assert(pnors != NULL); + +#pragma omp parallel for if (numPolys > BM_OMP_LIMIT) + for (i = 0; i < numPolys; i++) { + BKE_mesh_calc_poly_normal(&mpolys[i], mloop + mpolys[i].loopstart, mverts, pnors[i]); + } + return; + } + /* first go through and calculate normals for all the polys */ tnorms = MEM_callocN(sizeof(*tnorms) * numVerts, __func__); @@ -2037,7 +2048,7 @@ void BKE_mesh_calc_normals(Mesh *mesh) { BKE_mesh_calc_normals_poly(mesh->mvert, mesh->totvert, mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, - NULL); + NULL, false); } void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*faceNors_r)[3]) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 1ebe99eb660..c17830639e4 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -363,7 +363,9 @@ bool modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode return 1; } -CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode) +CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md, + CustomDataMask dataMask, int required_mode, + ModifierData *previewmd, CustomDataMask previewmask) { CDMaskLink *dataMasks = NULL; CDMaskLink *curr, *prev; @@ -374,10 +376,15 @@ CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierDat curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink"); - if (modifier_isEnabled(scene, md, required_mode)) + if (modifier_isEnabled(scene, md, required_mode)) { if (mti->requiredDataMask) curr->mask = mti->requiredDataMask(ob, md); + if (previewmd == md) { + curr->mask |= previewmask; + } + } + /* prepend new datamask */ curr->next = dataMasks; dataMasks = curr; diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 7b5b6a28421..1fbc2432595 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -503,7 +503,7 @@ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode) /* Non clipped mapping for strip-time <-> global time - * mode = eNlaTime_ConvertModesp[] -> NLATIME_CONVERT_* + * mode = eNlaTime_ConvertModes -> NLATIME_CONVERT_* * * Public API method - perform this mapping using the given AnimData block * and perform any necessary sanity checks on the value diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index f805005e911..d40e0daf247 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -150,6 +150,9 @@ static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node) ntype->initfunc_api(C, &ptr); } + if (node->id) + id_us_plus(node->id); + node->flag |= NODE_INIT; } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index be48c7cf12a..1d0b0deae7e 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -765,9 +765,6 @@ void BKE_texture_make_local(Tex *tex) if (tex->id.us == 1) { id_clear_lib_data(bmain, &tex->id); extern_local_texture(tex); - /* nodetree uses same lib */ - if (tex->nodetree) - tex->nodetree->id.lib = NULL; return; } @@ -827,9 +824,6 @@ void BKE_texture_make_local(Tex *tex) if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &tex->id); extern_local_texture(tex); - /* nodetree uses same lib */ - if (tex->nodetree) - tex->nodetree->id.lib = NULL; } else if (is_local && is_lib) { Tex *tex_new = BKE_texture_copy(tex); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index d556c75259b..9ae3c5cdfe1 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3602,18 +3602,18 @@ static bool stabilization_median_point_get(MovieTracking *tracking, int framenr, * NOTE: frame number should be in clip space, not scene space */ static void stabilization_calculate_data(MovieTracking *tracking, int framenr, float width, float height, - float firstmedian[2], float median[2], float loc[2], - float *scale, float *angle) + float firstmedian[2], float median[2], + float translation[2], float *scale, float *angle) { MovieTrackingStabilization *stab = &tracking->stabilization; *scale = (stab->scale - 1.0f) * stab->scaleinf + 1.0f; *angle = 0.0f; - loc[0] = (firstmedian[0] - median[0]) * width * (*scale); - loc[1] = (firstmedian[1] - median[1]) * height * (*scale); + translation[0] = (firstmedian[0] - median[0]) * width * (*scale); + translation[1] = (firstmedian[1] - median[1]) * height * (*scale); - mul_v2_fl(loc, stab->locinf); + mul_v2_fl(translation, stab->locinf); if ((stab->flag & TRACKING_STABILIZE_ROTATION) && stab->rot_track && stab->rotinf) { MovieTrackingMarker *marker; @@ -3635,8 +3635,8 @@ static void stabilization_calculate_data(MovieTracking *tracking, int framenr, f *angle *= stab->rotinf; /* convert to rotation around image center */ - loc[0] -= (x0 + (x - x0) * cosf(*angle) - (y - y0) * sinf(*angle) - x) * (*scale); - loc[1] -= (y0 + (x - x0) * sinf(*angle) + (y - y0) * cosf(*angle) - y) * (*scale); + translation[0] -= (x0 + (x - x0) * cosf(*angle) - (y - y0) * sinf(*angle) - x) * (*scale); + translation[1] -= (y0 + (x - x0) * sinf(*angle) + (y - y0) * cosf(*angle) - y) * (*scale); } } @@ -3679,7 +3679,7 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i */ for (cfra = sfra; cfra <= efra; cfra++) { float median[2]; - float loc[2], angle, tmp_scale; + float translation[2], angle, tmp_scale; int i; float mat[4][4]; float points[4][2] = {{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}}; @@ -3687,9 +3687,9 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i stabilization_median_point_get(tracking, cfra, median); - stabilization_calculate_data(tracking, cfra, width, height, firstmedian, median, loc, &tmp_scale, &angle); + stabilization_calculate_data(tracking, cfra, width, height, firstmedian, median, translation, &tmp_scale, &angle); - BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, 1.0f, angle, mat); + BKE_tracking_stabilization_data_to_mat4(width, height, aspect, translation, 1.0f, angle, mat); si = sin(angle); co = cos(angle); @@ -3715,8 +3715,8 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i const float rotDx[4][2] = {{1.0f, 0.0f}, {0.0f, -1.0f}, {-1.0f, 0.0f}, {0.0f, 1.0f}}; const float rotDy[4][2] = {{0.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, -1.0f}, {-1.0f, 0.0f}}; - float dx = loc[0] * rotDx[j][0] + loc[1] * rotDx[j][1], - dy = loc[0] * rotDy[j][0] + loc[1] * rotDy[j][1]; + float dx = translation[0] * rotDx[j][0] + translation[1] * rotDx[j][1], + dy = translation[0] * rotDy[j][0] + translation[1] * rotDy[j][1]; float w, h, E, F, G, H, I, J, K, S; @@ -3772,14 +3772,14 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i * NOTE: frame number should be in clip space, not scene space */ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, int width, int height, - float loc[2], float *scale, float *angle) + float translation[2], float *scale, float *angle) { float firstmedian[2], median[2]; MovieTrackingStabilization *stab = &tracking->stabilization; /* Early output if stabilization is disabled. */ if ((stab->flag & TRACKING_2D_STABILIZATION) == 0) { - zero_v2(loc); + zero_v2(translation); *scale = 1.0f; *angle = 0.0f; @@ -3803,16 +3803,18 @@ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, i if (stab->flag & TRACKING_AUTOSCALE) stabilization_calculate_autoscale_factor(tracking, width, height); - stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); + stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, + translation, scale, angle); stab->ok = TRUE; } else { - stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); + stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, + translation, scale, angle); } } else { - zero_v2(loc); + zero_v2(translation); *scale = 1.0f; *angle = 0.0f; } @@ -3824,7 +3826,7 @@ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, i * NOTE: frame number should be in clip space, not scene space */ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf *ibuf, - float loc[2], float *scale, float *angle) + float translation[2], float *scale, float *angle) { float tloc[2], tscale, tangle; MovieTrackingStabilization *stab = &tracking->stabilization; @@ -3836,16 +3838,16 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf void (*interpolation)(struct ImBuf *, struct ImBuf *, float, float, int, int) = NULL; int ibuf_flags; - if (loc) - copy_v2_v2(tloc, loc); + if (translation) + copy_v2_v2(tloc, translation); if (scale) tscale = *scale; /* Perform early output if no stabilization is used. */ if ((stab->flag & TRACKING_2D_STABILIZATION) == 0) { - if (loc) - zero_v2(loc); + if (translation) + zero_v2(translation); if (scale) *scale = 1.0f; @@ -3902,8 +3904,8 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf if (tmpibuf->rect_float) tmpibuf->userflags |= IB_RECT_INVALID; - if (loc) - copy_v2_v2(loc, tloc); + if (translation) + copy_v2_v2(translation, tloc); if (scale) *scale = tscale; @@ -3921,33 +3923,43 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf * NOTE: The reaosn it is 4x4 matrix is because it's * used for OpenGL drawing directly. */ -void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2], - float scale, float angle, float mat[4][4]) +void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, + float translation[2], float scale, float angle, + float mat[4][4]) { - float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4], amat[4][4], iamat[4][4]; - float svec[3] = {scale, scale, scale}; + float translation_mat[4][4], rotation_mat[4][4], scale_mat[4][4], + center_mat[4][4], inv_center_mat[4][4], + aspect_mat[4][4], inv_aspect_mat[4][4]; + float scale_vector[3] = {scale, scale, scale}; - unit_m4(rmat); - unit_m4(lmat); - unit_m4(smat); - unit_m4(cmat); - unit_m4(amat); + unit_m4(translation_mat); + unit_m4(rotation_mat); + unit_m4(scale_mat); + unit_m4(center_mat); + unit_m4(aspect_mat); /* aspect ratio correction matrix */ - amat[0][0] = 1.0f / aspect; - invert_m4_m4(iamat, amat); + aspect_mat[0][0] = 1.0f / aspect; + invert_m4_m4(inv_aspect_mat, aspect_mat); - /* image center as rotation center */ - cmat[3][0] = (float)width / 2.0f; - cmat[3][1] = (float)height / 2.0f; - invert_m4_m4(icmat, cmat); + /* image center as rotation center + * + * Rotation matrix is constructing in a way rotaion happens around image center, + * and it's matter of calculating trasnlation in a way, that applying translation + * after rotation would make it so rotation happens around median point of tracks + * used for translation stabilization. + */ + center_mat[3][0] = (float)width / 2.0f; + center_mat[3][1] = (float)height / 2.0f; + invert_m4_m4(inv_center_mat, center_mat); - size_to_mat4(smat, svec); /* scale matrix */ - add_v2_v2(lmat[3], loc); /* translation matrix */ - rotate_m4(rmat, 'Z', angle); /* rotation matrix */ + size_to_mat4(scale_mat, scale_vector); /* scale matrix */ + add_v2_v2(translation_mat[3], translation); /* translation matrix */ + rotate_m4(rotation_mat, 'Z', angle); /* rotation matrix */ /* compose transformation matrix */ - mul_serie_m4(mat, lmat, cmat, amat, rmat, iamat, smat, icmat, NULL); + mul_serie_m4(mat, translation_mat, center_mat, aspect_mat, rotation_mat, inv_aspect_mat, + scale_mat, inv_center_mat, NULL); } /*********************** Dopesheet functions *************************/ diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 050fcd2600b..206f829eaa8 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -179,9 +179,6 @@ void BKE_world_make_local(World *wrld) if (wrld->id.lib == NULL) return; if (wrld->id.us == 1) { id_clear_lib_data(bmain, &wrld->id); - /* nodetree uses same lib */ - if (wrld->nodetree) - wrld->nodetree->id.lib = NULL; return; } @@ -194,9 +191,6 @@ void BKE_world_make_local(World *wrld) if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &wrld->id); - /* nodetree uses same lib */ - if (wrld->nodetree) - wrld->nodetree->id.lib = NULL; } else if (is_local && is_lib) { World *wrld_new = BKE_world_copy(wrld); diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 56ac6c379c2..b7eeceae494 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -791,7 +791,10 @@ static bool bm_loop_reverse_loop(BMesh *bm, BMFace *f for (x = 0; x < sides; x++) { for (y = 0; y < x; y++) { swap_v3_v3(co[y * sides + x], co[sides * x + y]); + SWAP(float, co[y * sides + x][0], co[y * sides + x][1]); + SWAP(float, co[x * sides + y][0], co[x * sides + y][1]); } + SWAP(float, co[x * sides + x][0], co[x * sides + x][1]); } } } diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index bf7bfc1123c..9c85a4fc4e5 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -432,10 +432,8 @@ static void bm_loop_flip_disp(float source_axis_x[3], float source_axis_y[3], static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source) { MDisps *mdisps; - BMLoop *l_iter; - BMLoop *l_first; - float x, y, d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3]; - int ix, iy, res; + float d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3]; + int ix, res; float axis_x[3], axis_y[3]; /* ignore 2-edged faces */ @@ -467,10 +465,15 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source) res = (int)sqrt(mdisps->totdisp); d = 1.0f / (float)(res - 1); - for (x = 0.0f, ix = 0; ix < res; x += d, ix++) { + #pragma omp parallel for if(res > 3) + for (ix = 0; ix < res; ix++) { + float x = d * ix, y; + int iy; for (y = 0.0f, iy = 0; iy < res; y += d, iy++) { + BMLoop *l_iter; + BMLoop *l_first; float co1[3], co2[3], co[3]; - + copy_v3_v3(co1, e1); mul_v3_fl(co1, y); diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.cpp b/source/blender/compositor/nodes/COM_TrackPositionNode.cpp index f4efcfe27f0..c5474e0ce70 100644 --- a/source/blender/compositor/nodes/COM_TrackPositionNode.cpp +++ b/source/blender/compositor/nodes/COM_TrackPositionNode.cpp @@ -27,6 +27,8 @@ extern "C" { #include "DNA_movieclip_types.h" + + #include "BKE_node.h" } TrackPositionNode::TrackPositionNode(bNode *editorNode) : Node(editorNode) @@ -44,13 +46,21 @@ void TrackPositionNode::convertToOperations(ExecutionSystem *graph, CompositorCo NodeTrackPosData *trackpos_data = (NodeTrackPosData *) editorNode->storage; + int frame_number; + if (editorNode->custom1 == CMP_TRACKPOS_ABSOLUTE_FRAME) { + frame_number = editorNode->custom2; + } + else { + frame_number = context->getFramenumber(); + } + TrackPositionOperation *operationX = new TrackPositionOperation(); TrackPositionOperation *operationY = new TrackPositionOperation(); operationX->setMovieClip(clip); operationX->setTrackingObject(trackpos_data->tracking_object); operationX->setTrackName(trackpos_data->track_name); - operationX->setFramenumber(context->getFramenumber()); + operationX->setFramenumber(frame_number); operationX->setAxis(0); operationX->setPosition(editorNode->custom1); operationX->setRelativeFrame(editorNode->custom2); @@ -58,7 +68,7 @@ void TrackPositionNode::convertToOperations(ExecutionSystem *graph, CompositorCo operationY->setMovieClip(clip); operationY->setTrackingObject(trackpos_data->tracking_object); operationY->setTrackName(trackpos_data->track_name); - operationY->setFramenumber(context->getFramenumber()); + operationY->setFramenumber(frame_number); operationY->setAxis(1); operationY->setPosition(editorNode->custom1); operationY->setRelativeFrame(editorNode->custom2); diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp index e647ae975ff..4f00358633a 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp @@ -31,6 +31,7 @@ extern "C" { #include "BKE_movieclip.h" + #include "BKE_node.h" #include "BKE_tracking.h" } @@ -42,7 +43,7 @@ TrackPositionOperation::TrackPositionOperation() : NodeOperation() this->m_trackingObjectName[0] = 0; this->m_trackName[0] = 0; this->m_axis = 0; - this->m_position = POSITION_ABSOLUTE; + this->m_position = CMP_TRACKPOS_ABSOLUTE; this->m_relativeFrame = 0; } @@ -77,7 +78,7 @@ void TrackPositionOperation::initExecution() copy_v2_v2(this->m_markerPos, marker->pos); - if (this->m_position == POSITION_RELATIVE_START) { + if (this->m_position == CMP_TRACKPOS_RELATIVE_START) { int i; for (i = 0; i < track->markersnr; i++) { @@ -90,7 +91,7 @@ void TrackPositionOperation::initExecution() } } } - else if (this->m_position == POSITION_RELATIVE_FRAME) { + else if (this->m_position == CMP_TRACKPOS_RELATIVE_FRAME) { int relative_clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_relativeFrame); diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index b934719a92b..3f05b907ea0 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -39,12 +39,6 @@ */ class TrackPositionOperation : public NodeOperation { protected: - enum { - POSITION_ABSOLUTE = 0, - POSITION_RELATIVE_START, - POSITION_RELATIVE_FRAME - }; - MovieClip *m_movieClip; int m_framenumber; char m_trackingObjectName[64]; diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 00b8fc4535d..b2810031474 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -200,6 +200,22 @@ int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); /* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); +/* object_vgroup.c */ +typedef enum eVGroupSelect { + WT_VGROUP_ACTIVE = 1, + WT_VGROUP_BONE_SELECT = 2, + WT_VGROUP_BONE_DEFORM = 3, + WT_VGROUP_ALL = 4, +} eVGroupSelect; + +#define WT_VGROUP_MASK_ALL \ + ((1 << WT_VGROUP_ACTIVE) | \ + (1 << WT_VGROUP_BONE_SELECT) | \ + (1 << WT_VGROUP_BONE_DEFORM) | \ + (1 << WT_VGROUP_ALL)) + +bool *ED_vgroup_subset_from_select_type(struct Object *ob, eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index d431115d84e..875789c5758 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2128,8 +2128,11 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle changed = true; } else if (inbox) { - button_activate_state(C, but, BUTTON_STATE_EXIT); - retval = WM_UI_HANDLER_BREAK; + /* if we allow activation on key press, it gives problems launching operators [#35713] */ + if (event->val == KM_RELEASE) { + button_activate_state(C, but, BUTTON_STATE_EXIT); + retval = WM_UI_HANDLER_BREAK; + } } break; } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 89d481eac45..b6575f4eca0 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1752,7 +1752,7 @@ void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const ch if (ot->prop && WM_key_event_operator_string(C, ot->idname, layout->root->opcontext, NULL, false, keybuf, sizeof(keybuf))) { - namestr += BLI_snprintf(namestr, sizeof(namestr_buf) - (namestr - namestr_buf), "|%s", name); + namestr += BLI_snprintf(namestr, sizeof(namestr_buf) - (namestr - namestr_buf), "|%s", keybuf); } } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 8621a61a2d1..b764c70b111 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -835,25 +835,27 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step) /* apply step */ data->active += step; - if (data->items.totitem == 0) - data->active = 0; - else if (data->active > data->items.totitem) { + if (data->items.totitem == 0) { + data->active = -1; + } + else if (data->active >= data->items.totitem) { if (data->items.more) { data->items.offset++; - data->active = data->items.totitem; + data->active = data->items.totitem - 1; ui_searchbox_update(C, ar, but, false); } - else - data->active = data->items.totitem; + else { + data->active = data->items.totitem - 1; + } } - else if (data->active < 1) { + else if (data->active < 0) { if (data->items.offset) { data->items.offset--; - data->active = 1; + data->active = 0; ui_searchbox_update(C, ar, but, false); } - else if (data->active < 0) - data->active = 0; + else if (data->active < -1) + data->active = -1; } ED_region_tag_redraw(ar); @@ -913,15 +915,13 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar) but->func_arg2 = NULL; - if (data->active) { - char *name = data->items.names[data->active - 1]; - char *cpoin = strchr(name, '|'); + if (data->active != -1) { + const char *name = data->items.names[data->active]; + const char *name_sep = strchr(name, '|'); + + BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen); - if (cpoin) cpoin[0] = 0; - BLI_strncpy(but->editstr, name, data->items.maxstrlen); - if (cpoin) cpoin[0] = '|'; - - but->func_arg2 = data->items.pointers[data->active - 1]; + but->func_arg2 = data->items.pointers[data->active]; return true; } @@ -955,8 +955,8 @@ void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, const wmEvent *eve for (a = 0; a < data->items.totitem; a++) { ui_searchbox_butrect(&rect, data, a); if (BLI_rcti_isect_pt(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) { - if (data->active != a + 1) { - data->active = a + 1; + if (data->active != a) { + data->active = a; ui_searchbox_select(C, ar, but, 0); break; } @@ -980,7 +980,7 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) } else { data->items.offset_i = data->items.offset = 0; - data->active = 0; + data->active = -1; /* handle active */ if (but->search_func && but->func_arg2) { @@ -992,19 +992,19 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) if (data->items.totitem) { /* first case, begin of list */ if (data->items.offset_i < data->items.maxitem) { - data->active = data->items.offset_i + 1; + data->active = data->items.offset_i; data->items.offset_i = 0; } else { /* second case, end of list */ if (data->items.totitem - data->items.offset_i <= data->items.maxitem) { - data->active = 1 + data->items.offset_i - data->items.totitem + data->items.maxitem; + data->active = data->items.offset_i - data->items.totitem + data->items.maxitem; data->items.offset_i = data->items.totitem - data->items.maxitem; } else { /* center active item */ data->items.offset_i -= data->items.maxitem / 2; - data->active = 1 + data->items.maxitem / 2; + data->active = data->items.maxitem / 2; } } } @@ -1018,19 +1018,19 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) but->search_func(C, but->search_arg, but->editstr, &data->items); /* handle case where editstr is equal to one of items */ - if (reset && data->active == 0) { + if (reset && data->active == -1) { int a; for (a = 0; a < data->items.totitem; a++) { - char *cpoin = strchr(data->items.names[a], '|'); - - if (cpoin) cpoin[0] = 0; - if (0 == strcmp(but->editstr, data->items.names[a])) - data->active = a + 1; - if (cpoin) cpoin[0] = '|'; + const char *name = data->items.names[a]; + const char *name_sep = strchr(name, '|'); + if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) { + data->active = a; + break; + } } if (data->items.totitem == 1 && but->editstr[0]) - data->active = 1; + data->active = 0; } /* validate selected item */ @@ -1075,9 +1075,9 @@ static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) /* widget itself */ if (data->preview) - ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0); + ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a == data->active) ? UI_ACTIVE : 0); else - ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0); + ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a == data->active) ? UI_ACTIVE : 0); } /* indicate more */ @@ -1101,7 +1101,7 @@ static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) ui_searchbox_butrect(&rect, data, a); /* widget itself */ - ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0); + ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a == data->active) ? UI_ACTIVE : 0); } /* indicate more */ @@ -2090,7 +2090,7 @@ static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, in /* a HS circle, V slider, rgb/hsv/hex sliders */ -static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, int show_picker) +static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, bool show_picker) { static short colormode = 0; /* temp? 0=rgb, 1=hsv, 2=hex */ uiBut *bt; diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 8afd3049b84..f48e4ff5056 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -42,6 +42,7 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_group.h" +#include "BKE_library.h" #include "BKE_main.h" #include "BKE_report.h" #include "BKE_object.h" @@ -377,8 +378,50 @@ void OBJECT_OT_group_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static bool group_link_early_exit_check(Group *group, Object *object) +{ + GroupObject *group_object; + + for (group_object = group->gobject.first; group_object; group_object = group_object->next) { + if (group_object->ob == object) { + return true; + } + } + + return false; +} + +static bool check_group_contains_object_recursive(Group *group, Object *object) +{ + GroupObject *group_object; + + if ((group->id.flag & LIB_DOIT) == 0) { + /* Cycle already exists in groups, let's prevent further crappyness */ + return true; + } + + group->id.flag &= ~LIB_DOIT; + + for (group_object = group->gobject.first; group_object; group_object = group_object->next) { + Object *current_object = group_object->ob; + + if (current_object == object) { + return true; + } + + if (current_object->dup_group) { + if (check_group_contains_object_recursive(current_object->dup_group, object)) { + return true; + } + } + } + + return false; +} + static int group_link_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = ED_object_context(C); Group *group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); @@ -386,6 +429,25 @@ static int group_link_exec(bContext *C, wmOperator *op) if (ELEM(NULL, ob, group)) return OPERATOR_CANCELLED; + /* Early return check, if the object is already in group + * we could sckip all the dependency check and just consider + * operator is finished. + */ + if (group_link_early_exit_check(group, ob)) { + return OPERATOR_FINISHED; + } + + /* Adding object to group which is used as dupligroup for self is bad idea. + * + * It is also bad idea to add object to group which is in group which + * contains our current object. + */ + tag_main_lb(&bmain->group, TRUE); + if (ob->dup_group == group || check_group_contains_object_recursive(group, ob)) { + BKE_report(op->reports, RPT_ERROR, "Could not add the group because of dependency cycle detected"); + return OPERATOR_CANCELLED; + } + BKE_group_object_add(group, ob, scene, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 1089df2e00d..74f1515fe74 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -430,19 +430,6 @@ typedef enum WT_ReplaceMode { WT_REPLACE_EMPTY_WEIGHTS = 2 } WT_ReplaceMode; -typedef enum WT_VertexGroupSelect { - WT_VGROUP_ACTIVE = 1, - WT_VGROUP_BONE_SELECT = 2, - WT_VGROUP_BONE_DEFORM = 3, - WT_VGROUP_ALL = 4, -} WT_VertexGroupSelect; - -#define WT_VGROUP_MASK_ALL \ - ((1 << WT_VGROUP_ACTIVE) | \ - (1 << WT_VGROUP_BONE_SELECT) | \ - (1 << WT_VGROUP_BONE_DEFORM) | \ - (1 << WT_VGROUP_ALL)) - static EnumPropertyItem WT_vertex_group_mode_item[] = { {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"}, @@ -1179,7 +1166,7 @@ static void vgroup_duplicate(Object *ob) /** * Return the subset type of the Vertex Group Selection */ -static bool *vgroup_subset_from_select_type(Object *ob, WT_VertexGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count) +bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count) { bool *vgroup_validmap = NULL; *r_vgroup_tot = BLI_countlist(&ob->defbase); @@ -3010,11 +2997,11 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op) float offset = RNA_float_get(op->ptr, "offset"); float gain = RNA_float_get(op->ptr, "gain"); - WT_VertexGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); int subset_count, vgroup_tot; - bool *vgroup_validmap = vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_levels_subset(ob, vgroup_validmap, vgroup_tot, subset_count, offset, gain); MEM_freeN(vgroup_validmap); @@ -3192,11 +3179,11 @@ static int vertex_group_invert_exec(bContext *C, wmOperator *op) bool auto_assign = RNA_boolean_get(op->ptr, "auto_assign"); bool auto_remove = RNA_boolean_get(op->ptr, "auto_remove"); - WT_VertexGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); int subset_count, vgroup_tot; - bool *vgroup_validmap = vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_invert_subset(ob, vgroup_validmap, vgroup_tot, subset_count, auto_assign, auto_remove); MEM_freeN(vgroup_validmap); @@ -3300,11 +3287,11 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op) float limit = RNA_float_get(op->ptr, "limit"); bool keep_single = RNA_boolean_get(op->ptr, "keep_single"); - WT_VertexGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); int subset_count, vgroup_tot; - bool *vgroup_validmap = vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single); MEM_freeN(vgroup_validmap); @@ -3341,11 +3328,11 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) Object *ob = ED_object_context(C); const int limit = RNA_int_get(op->ptr, "limit"); - WT_VertexGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); int subset_count, vgroup_tot; - bool *vgroup_validmap = vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); int remove_tot = vgroup_limit_total_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit); MEM_freeN(vgroup_validmap); diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index da2f8bd2f9d..4e94e534c4d 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -442,7 +442,7 @@ static void render_endjob(void *rjv) /* XXX render stability hack */ G.is_rendering = FALSE; - WM_main_add_notifier(NC_WINDOW, NULL); + WM_main_add_notifier(NC_SCENE|ND_RENDER_RESULT, NULL); /* Partial render result will always update display buffer * for first render layer only. This is nice because you'll diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 69c1d2cf169..429156ea6a7 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1339,6 +1339,7 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space) sa1->headertype = sa2->headertype; sa1->spacetype = sa2->spacetype; + sa1->type = sa2->type; sa1->butspacetype = sa2->butspacetype; if (swap_space == 1) { diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 8fd2c4420f7..d1fd5093974 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -1428,15 +1428,16 @@ void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar) ibuf = ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle); if (ibuf) { - float loc[2]; + float translation[2]; float aspect = clip->tracking.camera.pixel_aspect; if (width != ibuf->x) - mul_v2_v2fl(loc, sc->loc, (float)width / ibuf->x); + mul_v2_v2fl(translation, sc->loc, (float)width / ibuf->x); else - copy_v2_v2(loc, sc->loc); + copy_v2_v2(translation, sc->loc); - BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, sc->scale, sc->angle, sc->stabmat); + BKE_tracking_stabilization_data_to_mat4(width, height, aspect, + translation, sc->scale, sc->angle, sc->stabmat); unit_m4(smat); smat[0][0] = 1.0f / width; diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index a51fef6c692..9d22d6fcc95 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1745,7 +1745,9 @@ void GRAPH_OT_euler_filter(wmOperatorType *ot) /* identifiers */ ot->name = "Euler Discontinuity Filter"; ot->idname = "GRAPH_OT_euler_filter"; - ot->description = "Fixes the most common causes of gimbal lock in the selected Euler Rotation F-Curves"; + ot->description = "Fix large jumps and flips in the selected " + "Euler Rotation F-Curves arising from rotation " + "values being clipped when baking physics"; /* api callbacks */ ot->exec = graphkeys_euler_filter_exec; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index e6b4f3cbefb..6ba736b75f3 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2216,7 +2216,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN uiItemR(layout, ptr, "position", 0, NULL, ICON_NONE); - if (node->custom1 == 2) { + if (ELEM(node->custom1, CMP_TRACKPOS_RELATIVE_FRAME, CMP_TRACKPOS_ABSOLUTE_FRAME)) { uiItemR(layout, ptr, "frame_relative", 0, NULL, ICON_NONE); } } diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index 509339dd3d4..d5224a37358 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -64,13 +64,11 @@ /* XXX Does some additional initialization on top of nodeAddNode * Can be used with both custom and static nodes, if idname==NULL the static int type will be used instead. - * Can be called from menus too, but they should do own undopush and redraws. */ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx, float locy) { SpaceNode *snode = CTX_wm_space_node(C); Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); bNode *node = NULL; node_deselect_all(snode); @@ -96,20 +94,6 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx ntreeUpdateTree(bmain, snode->edittree); ED_node_set_active(bmain, snode->edittree, node); - if (snode->nodetree->type == NTREE_COMPOSIT) { - if (ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) { - node->id = &scene->id; - } - else if (ELEM3(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_MOVIEDISTORTION, CMP_NODE_STABILIZE2D)) { - node->id = (ID *)scene->clip; - } - - ntreeCompositForceHidden(snode->edittree, scene); - } - - if (node->id) - id_us_plus(node->id); - if (snode->flag & SNODE_USE_HIDDEN_PREVIEW) node->flag &= ~NODE_PREVIEW; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index db10c1c5957..4793c9af068 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -105,8 +105,8 @@ typedef enum eWireDrawMode { typedef struct drawDMVerts_userData { BMEditMesh *em; - int sel; BMVert *eve_act; + char sel; /* cached theme values */ unsigned char th_editmesh_active[4]; @@ -2038,13 +2038,13 @@ static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) { BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); - int sel = *(((int **)userData)[1]); + const char sel = *(((char **)userData)[1]); if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT) == sel) { bglVertex3fv(cent); } } -static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, int sel) +static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, char sel) { void *ptrs[2] = {em, &sel}; @@ -2065,9 +2065,7 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float copy_v3_v3(no, no_f); } else { - no[0] = no_s[0] / 32767.0f; - no[1] = no_s[1] / 32767.0f; - no[2] = no_s[2] / 32767.0f; + normal_short_to_float_v3(no, no_s); } if (!data->uniform_scale) { @@ -2147,7 +2145,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3], } } -static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act, +static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act, RegionView3D *rv3d) { drawDMVerts_userData data; @@ -5092,7 +5090,7 @@ static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, flo /* place to add drawers */ -static void drawhandlesN(Nurb *nu, short sel, short hide_handles) +static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles) { BezTriple *bezt; float *fp; @@ -5187,7 +5185,7 @@ static void drawhandlesN_active(Nurb *nu) glLineWidth(1); } -static void drawvertsN(Nurb *nu, short sel, short hide_handles, void *lastsel) +static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, void *lastsel) { BezTriple *bezt; BPoint *bp; @@ -5450,7 +5448,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Curve *cu = ob->data; Nurb *nu; BevList *bl; - short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); + const bool hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0; int index; unsigned char wire_col[3]; @@ -5460,7 +5458,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + if (v3d->zbuf) glDepthFunc(GL_ALWAYS); /* first non-selected and active handles */ index = 0; @@ -5481,7 +5479,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, drawvertsN(nu, 0, hide_handles, NULL); } - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + if (v3d->zbuf) glDepthFunc(GL_LEQUAL); /* direction vectors for 3d curve paths * when at its lowest, don't render normals */ @@ -5526,13 +5524,13 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, } } - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + if (v3d->zbuf) glDepthFunc(GL_ALWAYS); for (nu = nurb; nu; nu = nu->next) { drawvertsN(nu, 1, hide_handles, cu->lastsel); } - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + if (v3d->zbuf) glDepthFunc(GL_LEQUAL); } /* draw a sphere for use as an empty drawtype */ diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 9d4da4c7e13..f7edb2949bc 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -70,6 +70,7 @@ #include "ED_armature.h" #include "ED_gpencil.h" +#include "ED_object.h" #include "ED_mesh.h" #include "ED_screen.h" #include "ED_transform.h" @@ -1005,8 +1006,10 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) if (dv && dv->totweight) { uiLayout *col; bDeformGroup *dg; - MDeformWeight *dw = dv->dw; unsigned int i; + int subset_count, vgroup_tot; + bool *vgroup_validmap; + eVGroupSelect subset_type = WT_VGROUP_ALL; int yco = 0; uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL); @@ -1016,16 +1019,21 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) uiBlockBeginAlign(block); - for (i = dv->totweight; i != 0; i--, dw++) { - dg = BLI_findlink(&ob->defbase, dw->def_nr); - if (dg) { - uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + dw->def_nr, dg->name, 0, yco, 180, 20, - &dw->weight, 0.0, 1.0, 1, 3, ""); - uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + dw->def_nr, "C", 180, yco, 20, 20, - NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts")); - yco -= 20; + vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) { + if (vgroup_validmap[i]) { + MDeformWeight *dw = defvert_find_index(dv, i); + if (dw) { + uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, dg->name, 0, yco, 180, 20, + &dw->weight, 0.0, 1.0, 1, 3, ""); + uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, "C", 180, yco, 20, 20, + NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts")); + yco -= 20; + } } } + MEM_freeN(vgroup_validmap); + yco -= 2; uiBlockEndAlign(block); diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h index b10a73277bf..7be51b37f7a 100644 --- a/source/blender/freestyle/FRS_freestyle.h +++ b/source/blender/freestyle/FRS_freestyle.h @@ -45,7 +45,7 @@ void FRS_set_context(struct bContext *C); void FRS_read_file(struct bContext *C); int FRS_is_freestyle_enabled(struct SceneRenderLayer *srl); void FRS_init_stroke_rendering(struct Render *re); -struct Render *FRS_do_stroke_rendering(struct Render *re, struct SceneRenderLayer *srl); +struct Render *FRS_do_stroke_rendering(struct Render *re, struct SceneRenderLayer *srl, int render); void FRS_finish_stroke_rendering(struct Render *re); void FRS_composite_result(struct Render *re, struct SceneRenderLayer *srl, struct Render *freestyle_render); void FRS_exit(void); diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index 436cdbfe6b5..dbf3fa8349e 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -833,17 +833,18 @@ void Controller::ResetRenderCount() _render_count = 0; } -Render *Controller::RenderStrokes(Render *re) +Render *Controller::RenderStrokes(Render *re, bool render) { _Chrono.start(); BlenderStrokeRenderer *blenderRenderer = new BlenderStrokeRenderer(re, ++_render_count); - _Canvas->Render(blenderRenderer); + if (render) + _Canvas->Render(blenderRenderer); real d = _Chrono.stop(); if (G.debug & G_DEBUG_FREESTYLE) { cout << "Temporary scene generation: " << d << endl; } _Chrono.start(); - Render *freestyle_render = blenderRenderer->RenderScene(re); + Render *freestyle_render = blenderRenderer->RenderScene(re, render); d = _Chrono.stop(); if (G.debug & G_DEBUG_FREESTYLE) { cout << "Stroke rendering : " << d << endl; diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h index 3315fe7e20b..c8eaaf5486b 100644 --- a/source/blender/freestyle/intern/application/Controller.h +++ b/source/blender/freestyle/intern/application/Controller.h @@ -86,7 +86,7 @@ public: void toggleEdgeTesselationNature(Nature::EdgeNature iNature); void DrawStrokes(); void ResetRenderCount(); - Render *RenderStrokes(Render *re); + Render *RenderStrokes(Render *re, bool render); void SwapStyleModules(unsigned i1, unsigned i2); void InsertStyleModule(unsigned index, const char *iFileName); void InsertStyleModule(unsigned index, const char *iName, struct Text *iText); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 294da904497..d665a0630ac 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -85,7 +85,7 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str //freestyle_scene->r.maximsize = old_scene->r.maximsize; /* DEPRECATED */ freestyle_scene->r.ocres = old_scene->r.ocres; freestyle_scene->r.color_mgt_flag = 0; // old_scene->r.color_mgt_flag; - freestyle_scene->r.scemode = old_scene->r.scemode & ~(R_SINGLE_LAYER); + freestyle_scene->r.scemode = old_scene->r.scemode & ~(R_SINGLE_LAYER | R_NO_FRAME_UPDATE); freestyle_scene->r.flag = old_scene->r.flag; freestyle_scene->r.threads = old_scene->r.threads; freestyle_scene->r.border.xmin = old_scene->r.border.xmin; @@ -476,7 +476,7 @@ Object *BlenderStrokeRenderer::NewMesh() const return ob; } -Render *BlenderStrokeRenderer::RenderScene(Render *re) +Render *BlenderStrokeRenderer::RenderScene(Render *re, bool render) { Camera *camera = (Camera *)freestyle_scene->camera->data; if (camera->clipend < _z) @@ -489,7 +489,7 @@ Render *BlenderStrokeRenderer::RenderScene(Render *re) Render *freestyle_render = RE_NewRender(freestyle_scene->id.name); - RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene); + RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene, render); return freestyle_render; } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h index 4d34f70f689..ae0e6bed3b2 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h @@ -51,7 +51,7 @@ public: Object *NewMesh() const; - Render *RenderScene(Render *re); + Render *RenderScene(Render *re, bool render); protected: Main *freestyle_bmain; diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index d5002d6fa39..8cb44d05b84 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -580,12 +580,15 @@ void FRS_init_stroke_rendering(Render *re) controller->ResetRenderCount(); } -Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl) +Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render) { Main bmain = {0}; Render *freestyle_render = NULL; Text *text, *next_text; + if (!render) + return controller->RenderStrokes(re, false); + RenderMonitor monitor(re); controller->setRenderMonitor(&monitor); @@ -619,7 +622,7 @@ Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl) re->i.infostr = NULL; freestyle_scene = re->scene; controller->DrawStrokes(); - freestyle_render = controller->RenderStrokes(re); + freestyle_render = controller->RenderStrokes(re, true); controller->CloseFile(); freestyle_scene = NULL; diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index d1e123cb826..9f9bc25a61c 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -309,7 +309,7 @@ typedef struct FreestyleFace { /* reserve 16 for ME_HIDE */ #define ME_EDGERENDER (1<<5) #define ME_LOOSEEDGE (1<<7) -/* #define ME_SEAM_LAST (1<<8) */ /* UNUSED */ +#define ME_EDGE_TMP_TAG (1 << 8) #define ME_SHARP (1<<9) /* only reason this flag remains a 'short' */ /* puno = vertexnormal (mface) */ diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 6be1933f12f..d733d9b4cb6 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -675,6 +675,7 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area) prop = RNA_def_property(srna, "shadow_soft_size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "area_size"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Shadow Soft Size", "Light size for ray shadow sampling (Raytraced shadows)"); RNA_def_property_update(prop, 0, "rna_Lamp_update"); @@ -739,11 +740,13 @@ static void rna_def_area_lamp(BlenderRNA *brna) prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "area_size"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Size", "Size of the area of the area Lamp, X direction size for Rectangle shapes"); RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); prop = RNA_def_property(srna, "size_y", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_float_sdna(prop, NULL, "area_sizey"); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Size Y", diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4433dc45601..a2bb1aff3b9 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -724,23 +724,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r node = nodeAddNode(C, ntree, type); BLI_assert(node && node->typeinfo); - /* XXX ugly stuff, should be done with specialized operators (after actual node creation)! */ - if (ntree->type == NTREE_COMPOSIT) { - if (ELEM4(node->type, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE, CMP_NODE_R_LAYERS)) { - /* annoying, find the node tree we are in, scene can be NULL */ - Scene *scene; - for (scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next) { - if (scene->nodetree == ntree) { - break; - } - } - node->id = (ID *)scene; - id_us_plus(node->id); - } - - ntreeCompositForceHidden(ntree, CTX_data_scene(C)); - } - else if (ntree->type == NTREE_TEXTURE) { + if (ntree->type == NTREE_TEXTURE) { ntreeTexCheckCyclics(ntree); } @@ -5730,9 +5714,14 @@ static void def_cmp_trackpos(StructRNA *srna) PropertyRNA *prop; static EnumPropertyItem position_items[] = { - {0, "ABSOLUTE", 0, "Absolute", "Output absolute position of a marker"}, - {1, "RELATIVE_START", 0, "Relative Start", "Output position of a marker relative to first marker of a track"}, - {2, "RELATIVE_FRAME", 0, "Relative Frame", "Output position of a marker relative to marker at given frame number"}, + {CMP_TRACKPOS_ABSOLUTE, "ABSOLUTE", 0, + "Absolute", "Output absolute position of a marker"}, + {CMP_TRACKPOS_RELATIVE_START, "RELATIVE_START", 0, + "Relative Start", "Output position of a marker relative to first marker of a track"}, + {CMP_TRACKPOS_RELATIVE_FRAME, "RELATIVE_FRAME", 0, + "Relative Frame", "Output position of a marker relative to marker at given frame number"}, + {CMP_TRACKPOS_ABSOLUTE_FRAME, "ABSOLUTE_FRAME", 0, + "Absolute Frame", "Output absolute position of a marker at given frame number"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ec672522a76..44eee642081 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1195,7 +1195,7 @@ static void rna_SceneRenderLayer_pass_update(Main *bmain, Scene *activescene, Po Scene *scene = (Scene *)ptr->id.data; if (scene->nodetree) - ntreeCompositForceHidden(scene->nodetree, scene); + ntreeCompositForceHidden(scene->nodetree); rna_Scene_glsl_update(bmain, activescene, ptr); } @@ -1255,6 +1255,12 @@ static void object_simplify_update(Object *ob) ModifierData *md; ParticleSystem *psys; + if ((ob->id.flag & LIB_DOIT) == 0) { + return; + } + + ob->id.flag &= ~LIB_DOIT; + for (md = ob->modifiers.first; md; md = md->next) { if (ELEM3(md->type, eModifierType_Subsurf, eModifierType_Multires, eModifierType_ParticleSystem)) { ob->recalc |= PSYS_RECALC_CHILD; @@ -1279,6 +1285,7 @@ static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), Poi Scene *sce_iter; Base *base; + tag_main_lb(&bmain->object, TRUE); for (SETLOOPER(sce, sce_iter, base)) object_simplify_update(base->object); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 4ef5f11c91f..97f229439e6 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -36,8 +36,6 @@ #include "BLI_utildefines.h" #include "BLI_math.h" -#include "BLI_edgehash.h" -#include "BLI_array.h" #include "BLI_string.h" #include "BKE_cdderivedmesh.h" @@ -48,6 +46,13 @@ #include "MOD_modifiertypes.h" #include "MOD_util.h" +#ifdef __GNUC__ +# pragma GCC diagnostic error "-Wsign-conversion" +#endif + +/* skip shell thickness for non-manifold edges, see [#35710] */ +#define USE_NONMANIFOLD_WORKAROUND + /* *** derived mesh high quality normal calculation function *** */ /* could be exposed for other functions to use */ @@ -56,21 +61,29 @@ typedef struct EdgeFaceRef { int f2; } EdgeFaceRef; -static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) +BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref) +{ + return !((edge_ref->f1 == 0) && (edge_ref->f2 == 0)); +} + +/** + * \param dm Mesh to calculate normals for. + * \param face_nors Precalculated face normals. + * \param r_vert_nors Return vert normals. + */ +static void dm_calc_normal(DerivedMesh *dm, float (*face_nors)[3], float (*r_vert_nors)[3]) { int i, numVerts, numEdges, numFaces; MPoly *mpoly, *mp; MLoop *mloop, *ml; + MEdge *medge, *ed; MVert *mvert, *mv; - float (*face_nors)[3]; - float *f_no; - int calc_face_nors = 0; - numVerts = dm->getNumVerts(dm); numEdges = dm->getNumEdges(dm); numFaces = dm->getNumPolys(dm); mpoly = dm->getPolyArray(dm); + medge = dm->getEdgeArray(dm); mvert = dm->getVertArray(dm); mloop = dm->getLoopArray(dm); @@ -82,93 +95,73 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) cddm->mvert = mv; #endif - face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); - if (!face_nors) { - calc_face_nors = 1; - face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, numFaces); - } - mv = mvert; mp = mpoly; { - EdgeHash *edge_hash = BLI_edgehash_new(); - EdgeHashIterator *edge_iter; - int edge_ref_count = 0; - unsigned int ed_v1, ed_v2; /* use when getting the key */ - EdgeFaceRef *edge_ref_array = MEM_callocN(numEdges * sizeof(EdgeFaceRef), "Edge Connectivity"); + EdgeFaceRef *edge_ref_array = MEM_callocN(sizeof(EdgeFaceRef) * (size_t)numEdges, "Edge Connectivity"); EdgeFaceRef *edge_ref; float edge_normal[3]; /* This loop adds an edge hash if its not there, and adds the face index */ for (i = 0; i < numFaces; i++, mp++) { - unsigned int ml_v1; - unsigned int ml_v2; int j; - f_no = face_nors[i]; - if (calc_face_nors) - BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no); - ml = mloop + mp->loopstart; - for (j = 0, ml_v2 = ml[mp->totloop - 1].v; - j < mp->totloop; - j++, ml++, ml_v2 = ml_v1) - { - ml_v1 = ml->v; + for (j = 0; j < mp->totloop; j++, ml++) { /* --- add edge ref to face --- */ - edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, ml_v1, ml_v2); - if (!edge_ref) { - edge_ref = &edge_ref_array[edge_ref_count++]; + edge_ref = &edge_ref_array[ml->e]; + if (!edgeref_is_init(edge_ref)) { edge_ref->f1 = i; edge_ref->f2 = -1; - BLI_edgehash_insert(edge_hash, ml_v1, ml_v2, edge_ref); + } + else if ((edge_ref->f1 != -1) && (edge_ref->f2 == -1)) { + edge_ref->f2 = i; } else { - edge_ref->f2 = i; + /* 3+ faces using an edge, we can't handle this usefully */ + edge_ref->f1 = edge_ref->f2 = -1; +#ifdef USE_NONMANIFOLD_WORKAROUND + medge[ml->e].flag |= ME_EDGE_TMP_TAG; +#endif } /* --- done --- */ } } - for (edge_iter = BLI_edgehashIterator_new(edge_hash); - !BLI_edgehashIterator_isDone(edge_iter); - BLI_edgehashIterator_step(edge_iter)) - { - /* Get the edge vert indices, and edge value (the face indices that use it)*/ - BLI_edgehashIterator_getKey(edge_iter, &ed_v1, &ed_v2); - edge_ref = BLI_edgehashIterator_getValue(edge_iter); + for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) { + /* Get the edge vert indices, and edge value (the face indices that use it) */ - if (edge_ref->f2 != -1) { - /* We have 2 faces using this edge, calculate the edges normal - * using the angle between the 2 faces as a weighting */ + if (edgeref_is_init(edge_ref) && (edge_ref->f1 != -1)) { + if (edge_ref->f2 != -1) { + /* We have 2 faces using this edge, calculate the edges normal + * using the angle between the 2 faces as a weighting */ #if 0 - add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); - normalize_v3(edge_normal); + add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); + normalize_v3(edge_normal); - mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); + mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); #else - mid_v3_v3v3_angle_weighted(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); + mid_v3_v3v3_angle_weighted(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); #endif + } + else { + /* only one face attached to that edge */ + /* an edge without another attached- the weight on this is undefined */ + copy_v3_v3(edge_normal, face_nors[edge_ref->f1]); + } + add_v3_v3(r_vert_nors[ed->v1], edge_normal); + add_v3_v3(r_vert_nors[ed->v2], edge_normal); } - else { - /* only one face attached to that edge */ - /* an edge without another attached- the weight on this is undefined */ - copy_v3_v3(edge_normal, face_nors[edge_ref->f1]); - } - add_v3_v3(temp_nors[ed_v1], edge_normal); - add_v3_v3(temp_nors[ed_v2], edge_normal); } - BLI_edgehashIterator_free(edge_iter); - BLI_edgehash_free(edge_hash, NULL); MEM_freeN(edge_ref_array); } /* normalize vertex normals and assign */ for (i = 0; i < numVerts; i++, mv++) { - if (normalize_v3(temp_nors[i]) == 0.0f) { - normal_short_to_float_v3(temp_nors[i], mv->no); + if (normalize_v3(r_vert_nors[i]) == 0.0f) { + normal_short_to_float_v3(r_vert_nors[i], mv->no); } } } @@ -222,7 +215,7 @@ static DerivedMesh *applyModifier( DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { - int i; + unsigned int i; DerivedMesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *) md; @@ -230,10 +223,11 @@ static DerivedMesh *applyModifier( MEdge *ed, *medge, *orig_medge; MLoop *ml, *mloop, *orig_mloop; MPoly *mp, *mpoly, *orig_mpoly; - const int numVerts = dm->getNumVerts(dm); - const int numEdges = dm->getNumEdges(dm); - const int numFaces = dm->getNumPolys(dm); - int numLoops = 0, newLoops = 0, newFaces = 0, newEdges = 0; + const unsigned int numVerts = (unsigned int)dm->getNumVerts(dm); + const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm); + const unsigned int numFaces = (unsigned int)dm->getNumPolys(dm); + const unsigned int numLoops = (unsigned int)dm->getNumLoops(dm); + unsigned int newLoops = 0, newFaces = 0, newEdges = 0; /* only use material offsets if we have 2 or more materials */ const short mat_nr_max = ob->totcol > 1 ? ob->totcol - 1 : 0; @@ -241,18 +235,22 @@ static DerivedMesh *applyModifier( const short mat_ofs_rim = mat_nr_max ? smd->mat_ofs_rim : 0; /* use for edges */ - int *new_vert_arr = NULL; - BLI_array_declare(new_vert_arr); - int *new_edge_arr = NULL; - BLI_array_declare(new_edge_arr); - int *old_vert_arr = MEM_callocN(sizeof(int) * numVerts, "old_vert_arr in solidify"); + /* over-alloc new_vert_arr, old_vert_arr */ + unsigned int *new_vert_arr = NULL; + STACK_DECLARE(new_vert_arr); - int *edge_users = NULL; + unsigned int *new_edge_arr = NULL; + STACK_DECLARE(new_edge_arr); + + unsigned int *old_vert_arr = MEM_callocN(sizeof(old_vert_arr) * (size_t)numVerts, "old_vert_arr in solidify"); + + unsigned int *edge_users = NULL; char *edge_order = NULL; float (*vert_nors)[3] = NULL; + float (*face_nors)[3] = NULL; - float (*face_nors_result)[3] = NULL; + const bool need_face_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) || (smd->flag & MOD_SOLIDIFY_EVEN); const float ofs_orig = -(((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); const float ofs_new = smd->offset + ofs_orig; @@ -268,25 +266,35 @@ static DerivedMesh *applyModifier( modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index); - numLoops = dm->numLoopData; - newLoops = 0; - orig_mvert = dm->getVertArray(dm); orig_medge = dm->getEdgeArray(dm); orig_mloop = dm->getLoopArray(dm); orig_mpoly = dm->getPolyArray(dm); + if (need_face_normals) { + /* calculate only face normals */ + face_nors = MEM_mallocN(sizeof(*face_nors) * (size_t)numFaces, __func__); + BKE_mesh_calc_normals_poly( + orig_mvert, (int)numVerts, + orig_mloop, orig_mpoly, + (int)numLoops, (int)numFaces, + face_nors, true); + } + + STACK_INIT(new_vert_arr); + STACK_INIT(new_edge_arr); + if (smd->flag & MOD_SOLIDIFY_RIM) { - EdgeHash *edgehash = BLI_edgehash_new(); - EdgeHashIterator *ehi; - unsigned int v1, v2; - int eidx; + unsigned int eidx; -#define INVALID_UNUSED -1 -#define INVALID_PAIR -2 +#define INVALID_UNUSED ((unsigned int)-1) +#define INVALID_PAIR ((unsigned int)-2) - edge_users = MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges"); - edge_order = MEM_mallocN(sizeof(char) * numEdges, "solid_mod eorder"); + new_vert_arr = MEM_mallocN(sizeof(*new_vert_arr) * (size_t)(numVerts * 2), __func__); + new_edge_arr = MEM_mallocN(sizeof(*new_edge_arr) * (size_t)((numEdges * 2) + numVerts), __func__); + + edge_users = MEM_mallocN(sizeof(*edge_users) * (size_t)numEdges, "solid_mod edges"); + edge_order = MEM_mallocN(sizeof(*edge_order) * (size_t)numEdges, "solid_mod eorder"); for (i = 0, mv = orig_mvert; i < numVerts; i++, mv++) { mv->flag &= ~ME_VERT_TMP_TAG; @@ -297,9 +305,8 @@ static DerivedMesh *applyModifier( fill_vn_i(edge_users, numEdges, INVALID_UNUSED); #endif - for (i = 0, ed = orig_medge; i < numEdges; i++, ed++) { - BLI_edgehash_insert(edgehash, ed->v1, ed->v2, SET_INT_IN_POINTER(i)); - edge_users[i] = INVALID_UNUSED; + for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) { + edge_users[eidx] = INVALID_UNUSED; } for (i = 0, mp = orig_mpoly; i < numFaces; i++, mp++) { @@ -315,7 +322,7 @@ static DerivedMesh *applyModifier( { ml_v1 = ml->v; /* add edge user */ - eidx = GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, ml_v1, ml_v2)); + eidx = ml->e; if (edge_users[eidx] == INVALID_UNUSED) { ed = orig_medge + eidx; edge_users[eidx] = (ml_v1 < ml_v2) == (ed->v1 < ed->v2) ? i : (i + numFaces); @@ -327,69 +334,63 @@ static DerivedMesh *applyModifier( } } -#undef INVALID_UNUSED -#undef INVALID_PAIR - - ehi = BLI_edgehashIterator_new(edgehash); - for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { - eidx = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); - if (edge_users[eidx] >= 0) { - BLI_edgehashIterator_getKey(ehi, &v1, &v2); - orig_mvert[v1].flag |= ME_VERT_TMP_TAG; - orig_mvert[v2].flag |= ME_VERT_TMP_TAG; - BLI_array_append(new_edge_arr, eidx); + for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) { + if (!ELEM(edge_users[eidx], INVALID_UNUSED, INVALID_PAIR)) { + orig_mvert[ed->v1].flag |= ME_VERT_TMP_TAG; + orig_mvert[ed->v2].flag |= ME_VERT_TMP_TAG; + STACK_PUSH(new_edge_arr, eidx); newFaces++; newLoops += 4; } } - BLI_edgehashIterator_free(ehi); + +#undef INVALID_UNUSED +#undef INVALID_PAIR for (i = 0, mv = orig_mvert; i < numVerts; i++, mv++) { if (mv->flag & ME_VERT_TMP_TAG) { - old_vert_arr[i] = BLI_array_count(new_vert_arr); - BLI_array_append(new_vert_arr, i); + old_vert_arr[i] = STACK_SIZE(new_vert_arr); + STACK_PUSH(new_vert_arr, i); newEdges++; mv->flag &= ~ME_VERT_TMP_TAG; } } - - BLI_edgehash_free(edgehash, NULL); } if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { - vert_nors = MEM_callocN(sizeof(float) * numVerts * 3, "mod_solid_vno_hq"); - dm_calc_normal(dm, vert_nors); + vert_nors = MEM_callocN(sizeof(float) * (size_t)numVerts * 3, "mod_solid_vno_hq"); + dm_calc_normal(dm, face_nors, vert_nors); } - result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, 0, - (numLoops * 2) + newLoops, (numFaces * 2) + newFaces); + result = CDDM_from_template(dm, + (int)(numVerts * 2), + (int)((numEdges * 2) + newEdges), 0, + (int)((numLoops * 2) + newLoops), + (int)((numFaces * 2) + newFaces)); mpoly = CDDM_get_polys(result); mloop = CDDM_get_loops(result); medge = CDDM_get_edges(result); mvert = CDDM_get_verts(result); - DM_copy_edge_data(dm, result, 0, 0, numEdges); - DM_copy_edge_data(dm, result, 0, numEdges, numEdges); + DM_copy_edge_data(dm, result, 0, 0, (int)numEdges); + DM_copy_edge_data(dm, result, 0, (int)numEdges, (int)numEdges); - DM_copy_vert_data(dm, result, 0, 0, numVerts); - DM_copy_vert_data(dm, result, 0, numVerts, numVerts); + DM_copy_vert_data(dm, result, 0, 0, (int)numVerts); + DM_copy_vert_data(dm, result, 0, (int)numVerts, (int)numVerts); - DM_copy_loop_data(dm, result, 0, 0, numLoops); - DM_copy_loop_data(dm, result, 0, numLoops, numLoops); + DM_copy_loop_data(dm, result, 0, 0, (int)numLoops); + DM_copy_loop_data(dm, result, 0, (int)numLoops, (int)numLoops); - DM_copy_poly_data(dm, result, 0, 0, numFaces); - DM_copy_poly_data(dm, result, 0, numFaces, numFaces); - - /* if the original has it, get the result so we can update it */ - face_nors_result = CustomData_get_layer(&result->polyData, CD_NORMAL); + DM_copy_poly_data(dm, result, 0, 0, (int)numFaces); + DM_copy_poly_data(dm, result, 0, (int)numFaces, (int)numFaces); /* flip normals */ mp = mpoly + numFaces; for (i = 0; i < dm->numPolyData; i++, mp++) { MLoop *ml2; - int e; + unsigned int e; int j; ml2 = mloop + mp->loopstart + dm->numLoopData; @@ -415,10 +416,6 @@ static DerivedMesh *applyModifier( ml2[j].e += numEdges; ml2[j].v += numVerts; } - - if (face_nors_result) { - negate_v3_v3(face_nors_result[numFaces + i], face_nors_result[i]); - } } for (i = 0, ed = medge + numEdges; i < numEdges; i++, ed++) { @@ -439,7 +436,7 @@ static DerivedMesh *applyModifier( if (do_clamp) { vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens"); - fill_vn_fl(vert_lens, numVerts, FLT_MAX); + fill_vn_fl(vert_lens, (int)numVerts, FLT_MAX); for (i = 0; i < numEdges; i++) { const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len); @@ -502,20 +499,13 @@ static DerivedMesh *applyModifier( } } else { - /* make a face normal layer if not present */ - float (*face_nors)[3]; - int face_nors_calc = 0; - +#ifdef USE_NONMANIFOLD_WORKAROUND + const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0; +#endif /* same as EM_solidify() in editmesh_lib.c */ float *vert_angles = MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */ float *vert_accum = vert_angles + numVerts; - int vidx; - - face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); - if (!face_nors) { - face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData); - face_nors_calc = 1; - } + unsigned int vidx; if (vert_nors == NULL) { vert_nors = MEM_mallocN(sizeof(float) * numVerts * 3, "mod_solid_vno"); @@ -529,22 +519,17 @@ static DerivedMesh *applyModifier( float nor_prev[3]; float nor_next[3]; - int i_this = mp->totloop - 1; + int i_curr = mp->totloop - 1; int i_next = 0; ml = &mloop[mp->loopstart]; - /* --- not related to angle calc --- */ - if (face_nors_calc) - BKE_mesh_calc_poly_normal(mp, ml, mvert, face_nors[i]); - /* --- end non-angle-calc section --- */ - - sub_v3_v3v3(nor_prev, mvert[ml[i_this - 1].v].co, mvert[ml[i_this].v].co); + sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co); normalize_v3(nor_prev); while (i_next < mp->totloop) { float angle; - sub_v3_v3v3(nor_next, mvert[ml[i_this].v].co, mvert[ml[i_next].v].co); + sub_v3_v3v3(nor_next, mvert[ml[i_curr].v].co, mvert[ml[i_next].v].co); normalize_v3(nor_next); angle = angle_normalized_v3v3(nor_prev, nor_next); @@ -553,15 +538,30 @@ static DerivedMesh *applyModifier( if (angle < FLT_EPSILON) { angle = FLT_EPSILON; } - vidx = ml[i_this].v; + + vidx = ml[i_curr].v; vert_accum[vidx] += angle; + +#ifdef USE_NONMANIFOLD_WORKAROUND + /* skip 3+ face user edges */ + if ((check_non_manifold == false) || + LIKELY(((orig_medge[ml[i_curr].e].flag & ME_EDGE_TMP_TAG) == 0) && + ((orig_medge[ml[i_next].e].flag & ME_EDGE_TMP_TAG) == 0))) + { + vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle; + } + else { + vert_angles[vidx] += angle; + } +#else vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle; +#endif /* --- end non-angle-calc section --- */ /* step */ copy_v3_v3(nor_prev, nor_next); - i_this = i_next; + i_curr = i_next; i_next++; } } @@ -591,7 +591,7 @@ static DerivedMesh *applyModifier( float *vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens"); const float offset = fabsf(smd->offset) * smd->offset_clamp; const float offset_sq = offset * offset; - fill_vn_fl(vert_lens, numVerts, FLT_MAX); + fill_vn_fl(vert_lens, (int)numVerts, FLT_MAX); for (i = 0; i < numEdges; i++) { const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len); @@ -633,10 +633,16 @@ static DerivedMesh *applyModifier( if (vert_nors) MEM_freeN(vert_nors); - /* flip vertex normals for copied verts */ - mv = mvert + numVerts; - for (i = 0; i < numVerts; i++, mv++) { - negate_v3_short(mv->no); + /* must recalculate normals with vgroups since they can displace unevenly [#26888] */ + if ((dm->dirty & DM_DIRTY_NORMALS) || (smd->flag & MOD_SOLIDIFY_RIM) || dvert) { + result->dirty |= DM_DIRTY_NORMALS; + } + else { + /* flip vertex normals for copied verts */ + mv = mvert + numVerts; + for (i = 0; i < numVerts; i++, mv++) { + negate_v3_short(mv->no); + } } if (smd->flag & MOD_SOLIDIFY_RIM) { @@ -653,8 +659,9 @@ static DerivedMesh *applyModifier( #define SOLIDIFY_SIDE_NORMALS #ifdef SOLIDIFY_SIDE_NORMALS + const bool do_side_normals = !(result->dirty & DM_DIRTY_NORMALS); /* annoying to allocate these since we only need the edge verts, */ - float (*edge_vert_nos)[3] = MEM_callocN(sizeof(float) * numVerts * 3, "solidify_edge_nos"); + float (*edge_vert_nos)[3] = do_side_normals ? MEM_callocN(sizeof(float) * numVerts * 3, __func__) : NULL; float nor[3]; #endif const unsigned char crease_rim = smd->crease_rim * 255.0f; @@ -663,7 +670,7 @@ static DerivedMesh *applyModifier( int *origindex_edge; int *orig_ed; - int j; + unsigned int j; if (crease_rim || crease_outer || crease_inner) { result->cd_flag |= ME_CDFLAG_EDGE_CREASE; @@ -690,37 +697,38 @@ static DerivedMesh *applyModifier( ml = mloop + (numLoops * 2); j = 0; for (i = 0; i < newFaces; i++, mp++) { - int eidx = new_edge_arr[i]; - int fidx = edge_users[eidx]; - int flip, k1, k2; + unsigned int eidx = new_edge_arr[i]; + unsigned int fidx = edge_users[eidx]; + int k1, k2; + bool flip; if (fidx >= numFaces) { fidx -= numFaces; - flip = TRUE; + flip = true; } else { - flip = FALSE; + flip = false; } ed = medge + eidx; /* copy most of the face settings */ - DM_copy_poly_data(dm, result, fidx, (numFaces * 2) + i, 1); - mp->loopstart = j + numLoops * 2; + DM_copy_poly_data(dm, result, (int)fidx, (int)((numFaces * 2) + i), 1); + mp->loopstart = (int)(j + numLoops * 2); mp->flag = mpoly[fidx].flag; /* notice we use 'mp->totloop' which is later overwritten, * we could lookup the original face but theres no point since this is a copy * and will have the same value, just take care when changing order of assignment */ k1 = mpoly[fidx].loopstart + (((edge_order[eidx] - 1) + mp->totloop) % mp->totloop); /* prev loop */ - k2 = mpoly[fidx].loopstart + (edge_order[eidx]); + k2 = mpoly[fidx].loopstart + (edge_order[eidx]); mp->totloop = 4; - CustomData_copy_data(&dm->loopData, &result->loopData, k2, numLoops * 2 + j + 0, 1); - CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops * 2 + j + 1, 1); - CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops * 2 + j + 2, 1); - CustomData_copy_data(&dm->loopData, &result->loopData, k2, numLoops * 2 + j + 3, 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k2, (int)(numLoops * 2 + j + 0), 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k1, (int)(numLoops * 2 + j + 1), 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k1, (int)(numLoops * 2 + j + 2), 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k2, (int)(numLoops * 2 + j + 3), 1); if (flip == FALSE) { ml[j].v = ed->v1; @@ -772,56 +780,58 @@ static DerivedMesh *applyModifier( } #ifdef SOLIDIFY_SIDE_NORMALS - normal_quad_v3(nor, - mvert[ml[j - 4].v].co, - mvert[ml[j - 3].v].co, - mvert[ml[j - 2].v].co, - mvert[ml[j - 1].v].co); + if (do_side_normals) { + normal_quad_v3(nor, + mvert[ml[j - 4].v].co, + mvert[ml[j - 3].v].co, + mvert[ml[j - 2].v].co, + mvert[ml[j - 1].v].co); - add_v3_v3(edge_vert_nos[ed->v1], nor); - add_v3_v3(edge_vert_nos[ed->v2], nor); - - if (face_nors_result) { - copy_v3_v3(face_nors_result[(numFaces * 2) + i], nor); + add_v3_v3(edge_vert_nos[ed->v1], nor); + add_v3_v3(edge_vert_nos[ed->v2], nor); } #endif } #ifdef SOLIDIFY_SIDE_NORMALS - ed = medge + (numEdges * 2); - for (i = 0; i < newEdges; i++, ed++) { - float nor_cpy[3]; - short *nor_short; - int k; + if (do_side_normals) { + ed = medge + (numEdges * 2); + for (i = 0; i < newEdges; i++, ed++) { + float nor_cpy[3]; + short *nor_short; + int k; - /* note, only the first vertex (lower half of the index) is calculated */ - normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]); + /* note, only the first vertex (lower half of the index) is calculated */ + normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]); - for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ - nor_short = mvert[*(&ed->v1 + k)].no; - normal_short_to_float_v3(nor, nor_short); - add_v3_v3(nor, nor_cpy); - normalize_v3(nor); - normal_float_to_short_v3(nor_short, nor); + for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ + nor_short = mvert[*(&ed->v1 + k)].no; + normal_short_to_float_v3(nor, nor_short); + add_v3_v3(nor, nor_cpy); + normalize_v3(nor); + normal_float_to_short_v3(nor_short, nor); + } } - } - MEM_freeN(edge_vert_nos); + MEM_freeN(edge_vert_nos); + } #endif - BLI_array_free(new_vert_arr); - BLI_array_free(new_edge_arr); + MEM_freeN(new_vert_arr); + MEM_freeN(new_edge_arr); + MEM_freeN(edge_users); MEM_freeN(edge_order); } + STACK_FREE(new_vert_arr); + STACK_FREE(new_edge_arr); + if (old_vert_arr) MEM_freeN(old_vert_arr); - /* must recalculate normals with vgroups since they can displace unevenly [#26888] */ - if ((dm->dirty & DM_DIRTY_NORMALS) || dvert) { - result->dirty |= DM_DIRTY_NORMALS; - } + if (face_nors) + MEM_freeN(face_nors); if (numFaces == 0 && numEdges != 0) { modifier_setError(md, "Faces needed for useful output"); @@ -832,11 +842,11 @@ static DerivedMesh *applyModifier( #undef SOLIDIFY_SIDE_NORMALS -static bool dependsOnNormals(ModifierData *md) +static bool dependsOnNormals(ModifierData *UNUSED(md)) { - SolidifyModifierData *smd = (SolidifyModifierData *) md; - - return (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) == 0; + /* even when we calculate our own normals, + * the vertex normals are used as a fallback */ + return true; } ModifierTypeInfo modifierType_Solidify = { diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index 896714338e5..626e7955b08 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -138,4 +138,6 @@ void register_node_type_cmp_switch(void); void register_node_type_cmp_pixelate(void); void register_node_type_cmp_trackpos(void); +void node_cmp_rlayers_force_hidden_passes(struct bNode *node); + #endif diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index a00ddf3d5e0..0b62481b2f7 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -74,7 +74,7 @@ static void composite_get_from_context(const bContext *C, bNodeTreeType *UNUSED( *r_ntree = scene->nodetree; /* update output sockets based on available layers */ - ntreeCompositForceHidden(scene->nodetree, scene); + ntreeCompositForceHidden(scene->nodetree); } @@ -262,69 +262,17 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int /* *********************************************** */ -static void set_output_visible(bNode *node, int passflag, int index, int pass) -{ - bNodeSocket *sock = BLI_findlink(&node->outputs, index); - /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden before */ - if (passflag & pass) - sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL); - else - sock->flag |= SOCK_UNAVAIL; -} - -/* clumsy checking... should do dynamic outputs once */ -static void force_hidden_passes(bNode *node, int passflag) -{ - bNodeSocket *sock; - - for (sock = node->outputs.first; sock; sock = sock->next) - sock->flag &= ~SOCK_UNAVAIL; - - set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED); - set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED); - - set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z); - set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL); - set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR); - set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV); - set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA); - set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE); - set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC); - set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW); - set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO); - set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT); - set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT); - set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB); - set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA); - set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST); - set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT); - set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT); - set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT); - set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR); - set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT); - set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR); -} - /* based on rules, force sockets hidden always */ -void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene) +void ntreeCompositForceHidden(bNodeTree *ntree) { bNode *node; if (ntree == NULL) return; for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == CMP_NODE_R_LAYERS) { - Scene *sce = node->id ? (Scene *)node->id : curscene; - SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1); - if (srl) - force_hidden_passes(node, srl->passflag); - } + if (node->type == CMP_NODE_R_LAYERS) + node_cmp_rlayers_force_hidden_passes(node); + /* XXX this stuff is called all the time, don't want that. * Updates should only happen when actually necessary. */ diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.c b/source/blender/nodes/composite/nodes/node_composite_composite.c index be9ed457150..c6c6a612bc4 100644 --- a/source/blender/nodes/composite/nodes/node_composite_composite.c +++ b/source/blender/nodes/composite/nodes/node_composite_composite.c @@ -31,6 +31,10 @@ #include "node_composite_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + /* **************** COMPOSITE ******************** */ static bNodeSocketTemplate cmp_node_composite_in[] = { { SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, @@ -39,12 +43,21 @@ static bNodeSocketTemplate cmp_node_composite_in[] = { { -1, 0, "" } }; +static void init(const bContext *C, PointerRNA *ptr) +{ + Scene *scene = CTX_data_scene(C); + bNode *node = ptr->data; + + node->id = &scene->id; +} + void register_node_type_cmp_composite(void) { static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_COMPOSITE, "Composite", NODE_CLASS_OUTPUT, NODE_PREVIEW); node_type_socket_templates(&ntype, cmp_node_composite_in, NULL); + ntype.initfunc_api = init; /* Do not allow muting for this node. */ node_type_internal_links(&ntype, NULL); diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c index a3311755717..c057ba904ba 100644 --- a/source/blender/nodes/composite/nodes/node_composite_defocus.c +++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c @@ -33,6 +33,10 @@ #include +#include "BKE_context.h" + +#include "RNA_access.h" + /* ************ qdn: Defocus node ****************** */ static bNodeSocketTemplate cmp_node_defocus_in[] = { { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, @@ -44,8 +48,10 @@ static bNodeSocketTemplate cmp_node_defocus_out[] = { { -1, 0, "" } }; -static void node_composit_init_defocus(bNodeTree *UNUSED(ntree), bNode *node) +static void node_composit_init_defocus(const bContext *C, PointerRNA *ptr) { + Scene *scene = CTX_data_scene(C); + bNode *node = ptr->data; /* qdn: defocus node */ NodeDefocus *nbd = MEM_callocN(sizeof(NodeDefocus), "node defocus data"); nbd->bktype = 0; @@ -59,6 +65,8 @@ static void node_composit_init_defocus(bNodeTree *UNUSED(ntree), bNode *node) nbd->scale = 1.f; nbd->no_zbuf = 1; node->storage = nbd; + + node->id = &scene->id; } void register_node_type_cmp_defocus(void) @@ -67,7 +75,7 @@ void register_node_type_cmp_defocus(void) cmp_node_type_base(&ntype, CMP_NODE_DEFOCUS, "Defocus", NODE_CLASS_OP_FILTER, 0); node_type_socket_templates(&ntype, cmp_node_defocus_in, cmp_node_defocus_out); - node_type_init(&ntype, node_composit_init_defocus); + ntype.initfunc_api = node_composit_init_defocus; node_type_storage(&ntype, "NodeDefocus", node_free_standard_storage, node_copy_standard_storage); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index b02bf6f438a..41f1f81e048 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -31,9 +31,16 @@ #include "node_composite_util.h" +#include "BLI_utildefines.h" + +#include "DNA_scene_types.h" + +#include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" +#include "RNA_access.h" + /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ static bNodeSocketTemplate cmp_node_rlayers_out[] = { @@ -347,6 +354,77 @@ void register_node_type_cmp_image(void) /* **************** RENDER RESULT ******************** */ +static void set_output_visible(bNode *node, int passflag, int index, int pass) +{ + bNodeSocket *sock = BLI_findlink(&node->outputs, index); + /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden before */ + if (passflag & pass) + sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL); + else + sock->flag |= SOCK_UNAVAIL; +} + +/* clumsy checking... should do dynamic outputs once */ +void node_cmp_rlayers_force_hidden_passes(bNode *node) +{ + Scene *scene = (Scene *)node->id; + SceneRenderLayer *srl; + int passflag; + bNodeSocket *sock; + + /* must always have valid scene pointer */ + BLI_assert(scene != NULL); + + srl = BLI_findlink(&scene->r.layers, node->custom1); + if (!srl) + return; + + passflag = srl->passflag; + + for (sock = node->outputs.first; sock; sock = sock->next) + sock->flag &= ~SOCK_UNAVAIL; + + set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED); + set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED); + + set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z); + set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL); + set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR); + set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV); + set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA); + set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE); + set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC); + set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW); + set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO); + set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT); + set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT); + set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB); + set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA); + set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST); + set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT); + set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT); + set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT); + set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR); + set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT); + set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR); +} + +static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr) +{ + Scene *scene = CTX_data_scene(C); + bNode *node = ptr->data; + + node->id = &scene->id; + + node_cmp_rlayers_force_hidden_passes(node); +} + static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree) { if (strcmp(ntree->idname, "CompositorNodeTree") == 0) { @@ -371,6 +449,7 @@ void register_node_type_cmp_rlayers(void) cmp_node_type_base(&ntype, CMP_NODE_R_LAYERS, "Render Layers", NODE_CLASS_INPUT, NODE_PREVIEW); node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); + ntype.initfunc_api = node_composit_init_rlayers; ntype.poll = node_composit_poll_rlayers; nodeRegisterType(&ntype); diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c index b42b8d36c0c..fc0d8060644 100644 --- a/source/blender/nodes/composite/nodes/node_composite_movieclip.c +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c @@ -33,6 +33,10 @@ #include "node_composite_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + static bNodeSocketTemplate cmp_node_movieclip_out[] = { { SOCK_RGBA, 0, N_("Image")}, { SOCK_FLOAT, 0, N_("Alpha")}, @@ -43,10 +47,13 @@ static bNodeSocketTemplate cmp_node_movieclip_out[] = { { -1, 0, "" } }; -static void init(bNodeTree *UNUSED(ntree), bNode *node) +static void init(const bContext *C, PointerRNA *ptr) { + bNode *node = ptr->data; + Scene *scene = CTX_data_scene(C); MovieClipUser *user = MEM_callocN(sizeof(MovieClipUser), "node movie clip user"); + node->id = (ID *)scene->clip; node->storage = user; user->framenr = 1; } @@ -57,7 +64,7 @@ void register_node_type_cmp_movieclip(void) cmp_node_type_base(&ntype, CMP_NODE_MOVIECLIP, "Movie Clip", NODE_CLASS_INPUT, NODE_PREVIEW); node_type_socket_templates(&ntype, NULL, cmp_node_movieclip_out); - node_type_init(&ntype, init); + ntype.initfunc_api = init; node_type_storage(&ntype, "MovieClipUser", node_free_standard_storage, node_copy_standard_storage); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c index 103a05f900e..b110cffd080 100644 --- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c @@ -32,6 +32,10 @@ #include "node_composite_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_moviedistortion_in[] = { @@ -52,6 +56,14 @@ static const char *label(bNode *node) return IFACE_("Distortion"); } +static void init(const bContext *C, PointerRNA *ptr) +{ + bNode *node = ptr->data; + Scene *scene = CTX_data_scene(C); + + node->id = (ID *)scene->clip; +} + static void storage_free(bNode *node) { if (node->storage) @@ -74,6 +86,7 @@ void register_node_type_cmp_moviedistortion(void) node_type_socket_templates(&ntype, cmp_node_moviedistortion_in, cmp_node_moviedistortion_out); node_type_label(&ntype, label); + ntype.initfunc_api = init; node_type_storage(&ntype, NULL, storage_free, storage_copy); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c index a6c59c1bc91..90b21f1bab0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c +++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c @@ -179,6 +179,8 @@ static void init_output_file(const bContext *C, PointerRNA *ptr) ImageFormatData *format = NULL; node->storage = nimf; + node->id = &scene->id; + if (scene) { RenderData *rd = &scene->r; diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c index 6d1cd56fa4a..c3eb44281f5 100644 --- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c @@ -32,6 +32,8 @@ #include "node_composite_util.h" +#include "BKE_image.h" + /* **************** SPLIT VIEWER ******************** */ static bNodeSocketTemplate cmp_node_splitviewer_in[] = { { SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, @@ -47,6 +49,8 @@ static void node_composit_init_splitviewer(bNodeTree *UNUSED(ntree), bNode *node iuser->fie_ima = 2; iuser->ok = 1; node->custom1 = 50; /* default 50% split */ + + node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); } void register_node_type_cmp_splitviewer(void) diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c index 2daf240ab18..28e2a2a205b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c @@ -33,6 +33,10 @@ #include "node_composite_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_stabilize2d_in[] = { @@ -45,8 +49,13 @@ static bNodeSocketTemplate cmp_node_stabilize2d_out[] = { { -1, 0, "" } }; -static void init(bNodeTree *UNUSED(ntree), bNode *node) +static void init(const bContext *C, PointerRNA *ptr) { + bNode *node = ptr->data; + Scene *scene = CTX_data_scene(C); + + node->id = (ID *)scene->clip; + /* default to bilinear, see node_sampler_type_items in rna_nodetree.c */ node->custom1 = 1; } @@ -57,7 +66,7 @@ void register_node_type_cmp_stabilize2d(void) cmp_node_type_base(&ntype, CMP_NODE_STABILIZE2D, "Stabilize 2D", NODE_CLASS_DISTORT, 0); node_type_socket_templates(&ntype, cmp_node_stabilize2d_in, cmp_node_stabilize2d_out); - node_type_init(&ntype, init); + ntype.initfunc_api = init; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c index 54d3f372c50..4b96270d36c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_viewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c @@ -32,6 +32,8 @@ #include "node_composite_util.h" +#include "BKE_image.h" + /* **************** VIEWER ******************** */ static bNodeSocketTemplate cmp_node_viewer_in[] = { @@ -50,6 +52,8 @@ static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode *node) iuser->ok = 1; node->custom3 = 0.5f; node->custom4 = 0.5f; + + node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); } void register_node_type_cmp_viewer(void) diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index e7c0b7b8811..481758db252 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -180,7 +180,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) DriverVar *dvar; double result = 0.0; /* default return */ - char *expr = NULL; + const char *expr; short targets_ok = 1; int i; @@ -192,9 +192,9 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) if (!(G.f & G_SCRIPT_AUTOEXEC)) { if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) { G.f |= G_SCRIPT_AUTOEXEC_FAIL; - BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Driver '%s'", driver->expression); + BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Driver '%s'", expr); - printf("skipping driver '%s', automatic scripts are disabled\n", driver->expression); + printf("skipping driver '%s', automatic scripts are disabled\n", expr); } return 0.0f; } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 79f856344d3..feffea20553 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -731,7 +731,7 @@ void BPY_modules_load_user(bContext *C) if (!(G.f & G_SCRIPT_AUTOEXEC)) { if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) { G.f |= G_SCRIPT_AUTOEXEC_FAIL; - BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Register Text '%s'", text->id.name + 2); + BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Text '%s'", text->id.name + 2); printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name + 2); } diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 52d42cd20a4..118d0036464 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -226,7 +226,7 @@ void RE_TileProcessor(struct Render *re); void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene, struct SceneRenderLayer *srl, struct Object *camera_override, unsigned int lay, int frame, const short write_still); void RE_BlenderAnim(struct Render *re, struct Main *bmain, struct Scene *scene, struct Object *camera_override, unsigned int lay, int sfra, int efra, int tfra); #ifdef WITH_FREESTYLE -void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene); +void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene, int render); #endif /* error reporting */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index c8f8f844e5f..068df215edb 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1081,7 +1081,7 @@ static void threaded_tile_processor(Render *re) } #ifdef WITH_FREESTYLE -static void add_freestyle(Render *re); +static void add_freestyle(Render *re, int render); static void free_all_freestyle_renders(void); #endif @@ -1097,7 +1097,7 @@ void RE_TileProcessor(Render *re) /* Freestyle */ if (re->r.mode & R_EDGE_FRS) { if (!re->test_break(re->tbh)) { - add_freestyle(re); + add_freestyle(re, 1); free_all_freestyle_renders(); @@ -1150,7 +1150,7 @@ static void do_render_3d(Render *re) /* Freestyle */ if (re->r.mode & R_EDGE_FRS) if (!re->test_break(re->tbh)) - add_freestyle(re); + add_freestyle(re, 1); #endif /* do left-over 3d post effects (flares) */ @@ -1633,7 +1633,7 @@ static void render_composit_stats(void *UNUSED(arg), char *str) #ifdef WITH_FREESTYLE /* invokes Freestyle stroke rendering */ -static void add_freestyle(Render *re) +static void add_freestyle(Render *re, int render) { SceneRenderLayer *srl, *actsrl; LinkData *link; @@ -1659,7 +1659,7 @@ static void add_freestyle(Render *re) if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl) continue; if (FRS_is_freestyle_enabled(srl)) { - link->data = (void *)FRS_do_stroke_rendering(re, srl); + link->data = (void *)FRS_do_stroke_rendering(re, srl, render); } } @@ -1853,6 +1853,11 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) for (scene = re->main->scene.first; scene; scene = scene->id.next) scene->id.flag |= LIB_DOIT; +#ifdef WITH_FREESTYLE + for (scene = re->freestyle_bmain.scene.first; scene; scene = scene->id.next) + scene->id.flag &= ~LIB_DOIT; +#endif + for (node = ntree->nodes.first; node; node = node->next) { if (node->type == CMP_NODE_R_LAYERS) { Scene *nodescene = (Scene *)node->id; @@ -1876,7 +1881,16 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) re->display_init(re->dih, re->result); re->display_clear(re->dch, re->result); +#ifdef WITH_FREESTYLE + if (re->r.mode & R_EDGE_FRS) + add_freestyle(re, 0); +#endif + do_merge_fullsample(re, ntree); + +#ifdef WITH_FREESTYLE + free_all_freestyle_renders(); +#endif } /* returns fully composited render-result on given time step (in RenderData) */ @@ -2445,11 +2459,12 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr } #ifdef WITH_FREESTYLE -void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene) +void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render) { re->result_ok= 0; if (render_initialize_from_main(re, bmain, scene, NULL, NULL, scene->lay, 0, 0)) { - do_render_fields_blur_3d(re); + if (render) + do_render_fields_blur_3d(re); } re->result_ok = 1; }