Merged changes in the trunk up to revision 54594.

This commit is contained in:
Tamito Kajiyama 2013-02-16 18:38:03 +00:00
commit 92436c94d3
267 changed files with 2724 additions and 1316 deletions

@ -518,88 +518,89 @@ def data_to_c_simple(FILE_FROM):
data_to_c(FILE_FROM, FILE_TO, VAR_NAME) data_to_c(FILE_FROM, FILE_TO, VAR_NAME)
data_to_c("source/blender/compositor/operations/COM_OpenCLKernels.cl", if B.targets != ['cudakernels']:
data_to_c("source/blender/compositor/operations/COM_OpenCLKernels.cl",
B.root_build_dir + "data_headers/COM_OpenCLKernels.cl.h", B.root_build_dir + "data_headers/COM_OpenCLKernels.cl.h",
"datatoc_COM_OpenCLKernels_cl") "datatoc_COM_OpenCLKernels_cl")
data_to_c_simple("release/datafiles/startup.blend") data_to_c_simple("release/datafiles/startup.blend")
data_to_c_simple("release/datafiles/preview.blend") data_to_c_simple("release/datafiles/preview.blend")
data_to_c_simple("release/datafiles/preview_cycles.blend") data_to_c_simple("release/datafiles/preview_cycles.blend")
# --- glsl --- # --- glsl ---
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl") data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl") data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl") data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl") data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl") data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl") data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl") data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl")
# --- blender --- # --- blender ---
data_to_c_simple("release/datafiles/bfont.pfb") data_to_c_simple("release/datafiles/bfont.pfb")
data_to_c_simple("release/datafiles/bfont.ttf") data_to_c_simple("release/datafiles/bfont.ttf")
data_to_c_simple("release/datafiles/bmonofont.ttf") data_to_c_simple("release/datafiles/bmonofont.ttf")
data_to_c_simple("release/datafiles/splash.png") data_to_c_simple("release/datafiles/splash.png")
data_to_c_simple("release/datafiles/blender_icons16.png") data_to_c_simple("release/datafiles/blender_icons16.png")
data_to_c_simple("release/datafiles/blender_icons32.png") data_to_c_simple("release/datafiles/blender_icons32.png")
data_to_c_simple("release/datafiles/prvicons.png") data_to_c_simple("release/datafiles/prvicons.png")
data_to_c_simple("release/datafiles/brushicons/add.png") data_to_c_simple("release/datafiles/brushicons/add.png")
data_to_c_simple("release/datafiles/brushicons/blob.png") data_to_c_simple("release/datafiles/brushicons/blob.png")
data_to_c_simple("release/datafiles/brushicons/blur.png") data_to_c_simple("release/datafiles/brushicons/blur.png")
data_to_c_simple("release/datafiles/brushicons/clay.png") data_to_c_simple("release/datafiles/brushicons/clay.png")
data_to_c_simple("release/datafiles/brushicons/claystrips.png") data_to_c_simple("release/datafiles/brushicons/claystrips.png")
data_to_c_simple("release/datafiles/brushicons/clone.png") data_to_c_simple("release/datafiles/brushicons/clone.png")
data_to_c_simple("release/datafiles/brushicons/crease.png") data_to_c_simple("release/datafiles/brushicons/crease.png")
data_to_c_simple("release/datafiles/brushicons/darken.png") data_to_c_simple("release/datafiles/brushicons/darken.png")
data_to_c_simple("release/datafiles/brushicons/draw.png") data_to_c_simple("release/datafiles/brushicons/draw.png")
data_to_c_simple("release/datafiles/brushicons/fill.png") data_to_c_simple("release/datafiles/brushicons/fill.png")
data_to_c_simple("release/datafiles/brushicons/flatten.png") data_to_c_simple("release/datafiles/brushicons/flatten.png")
data_to_c_simple("release/datafiles/brushicons/grab.png") data_to_c_simple("release/datafiles/brushicons/grab.png")
data_to_c_simple("release/datafiles/brushicons/inflate.png") data_to_c_simple("release/datafiles/brushicons/inflate.png")
data_to_c_simple("release/datafiles/brushicons/layer.png") data_to_c_simple("release/datafiles/brushicons/layer.png")
data_to_c_simple("release/datafiles/brushicons/lighten.png") data_to_c_simple("release/datafiles/brushicons/lighten.png")
data_to_c_simple("release/datafiles/brushicons/mask.png") data_to_c_simple("release/datafiles/brushicons/mask.png")
data_to_c_simple("release/datafiles/brushicons/mix.png") data_to_c_simple("release/datafiles/brushicons/mix.png")
data_to_c_simple("release/datafiles/brushicons/multiply.png") data_to_c_simple("release/datafiles/brushicons/multiply.png")
data_to_c_simple("release/datafiles/brushicons/nudge.png") data_to_c_simple("release/datafiles/brushicons/nudge.png")
data_to_c_simple("release/datafiles/brushicons/pinch.png") data_to_c_simple("release/datafiles/brushicons/pinch.png")
data_to_c_simple("release/datafiles/brushicons/scrape.png") data_to_c_simple("release/datafiles/brushicons/scrape.png")
data_to_c_simple("release/datafiles/brushicons/smear.png") data_to_c_simple("release/datafiles/brushicons/smear.png")
data_to_c_simple("release/datafiles/brushicons/smooth.png") data_to_c_simple("release/datafiles/brushicons/smooth.png")
data_to_c_simple("release/datafiles/brushicons/snake_hook.png") data_to_c_simple("release/datafiles/brushicons/snake_hook.png")
data_to_c_simple("release/datafiles/brushicons/soften.png") data_to_c_simple("release/datafiles/brushicons/soften.png")
data_to_c_simple("release/datafiles/brushicons/subtract.png") data_to_c_simple("release/datafiles/brushicons/subtract.png")
data_to_c_simple("release/datafiles/brushicons/texdraw.png") data_to_c_simple("release/datafiles/brushicons/texdraw.png")
data_to_c_simple("release/datafiles/brushicons/thumb.png") data_to_c_simple("release/datafiles/brushicons/thumb.png")
data_to_c_simple("release/datafiles/brushicons/twist.png") data_to_c_simple("release/datafiles/brushicons/twist.png")
data_to_c_simple("release/datafiles/brushicons/vertexdraw.png") data_to_c_simple("release/datafiles/brushicons/vertexdraw.png")
data_to_c_simple("release/datafiles/matcaps/mc01.jpg") data_to_c_simple("release/datafiles/matcaps/mc01.jpg")
data_to_c_simple("release/datafiles/matcaps/mc02.jpg") data_to_c_simple("release/datafiles/matcaps/mc02.jpg")
data_to_c_simple("release/datafiles/matcaps/mc03.jpg") data_to_c_simple("release/datafiles/matcaps/mc03.jpg")
data_to_c_simple("release/datafiles/matcaps/mc04.jpg") data_to_c_simple("release/datafiles/matcaps/mc04.jpg")
data_to_c_simple("release/datafiles/matcaps/mc05.jpg") data_to_c_simple("release/datafiles/matcaps/mc05.jpg")
data_to_c_simple("release/datafiles/matcaps/mc06.jpg") data_to_c_simple("release/datafiles/matcaps/mc06.jpg")
data_to_c_simple("release/datafiles/matcaps/mc07.jpg") data_to_c_simple("release/datafiles/matcaps/mc07.jpg")
data_to_c_simple("release/datafiles/matcaps/mc08.jpg") data_to_c_simple("release/datafiles/matcaps/mc08.jpg")
data_to_c_simple("release/datafiles/matcaps/mc09.jpg") data_to_c_simple("release/datafiles/matcaps/mc09.jpg")
data_to_c_simple("release/datafiles/matcaps/mc10.jpg") data_to_c_simple("release/datafiles/matcaps/mc10.jpg")
data_to_c_simple("release/datafiles/matcaps/mc11.jpg") data_to_c_simple("release/datafiles/matcaps/mc11.jpg")
data_to_c_simple("release/datafiles/matcaps/mc12.jpg") data_to_c_simple("release/datafiles/matcaps/mc12.jpg")
data_to_c_simple("release/datafiles/matcaps/mc13.jpg") data_to_c_simple("release/datafiles/matcaps/mc13.jpg")
data_to_c_simple("release/datafiles/matcaps/mc14.jpg") data_to_c_simple("release/datafiles/matcaps/mc14.jpg")
data_to_c_simple("release/datafiles/matcaps/mc15.jpg") data_to_c_simple("release/datafiles/matcaps/mc15.jpg")
data_to_c_simple("release/datafiles/matcaps/mc16.jpg") data_to_c_simple("release/datafiles/matcaps/mc16.jpg")
data_to_c_simple("release/datafiles/matcaps/mc17.jpg") data_to_c_simple("release/datafiles/matcaps/mc17.jpg")
data_to_c_simple("release/datafiles/matcaps/mc18.jpg") data_to_c_simple("release/datafiles/matcaps/mc18.jpg")
data_to_c_simple("release/datafiles/matcaps/mc19.jpg") data_to_c_simple("release/datafiles/matcaps/mc19.jpg")
data_to_c_simple("release/datafiles/matcaps/mc20.jpg") data_to_c_simple("release/datafiles/matcaps/mc20.jpg")
data_to_c_simple("release/datafiles/matcaps/mc21.jpg") data_to_c_simple("release/datafiles/matcaps/mc21.jpg")
data_to_c_simple("release/datafiles/matcaps/mc22.jpg") data_to_c_simple("release/datafiles/matcaps/mc22.jpg")
data_to_c_simple("release/datafiles/matcaps/mc23.jpg") data_to_c_simple("release/datafiles/matcaps/mc23.jpg")
data_to_c_simple("release/datafiles/matcaps/mc24.jpg") data_to_c_simple("release/datafiles/matcaps/mc24.jpg")
##### END DATAFILES ########## ##### END DATAFILES ##########
@ -869,6 +870,8 @@ if env['OURPLATFORM']=='linux':
td, tf = os.path.split(targetdir) td, tf = os.path.split(targetdir)
iconinstall.append(env.Install(dir=td, source=srcfile)) iconinstall.append(env.Install(dir=td, source=srcfile))
scriptinstall.append(env.Install(dir=env['BF_INSTALLDIR'], source='release/bin/blender-thumbnailer.py'))
# dlls for linuxcross # dlls for linuxcross
# TODO - add more libs, for now this lets blenderlite run # TODO - add more libs, for now this lets blenderlite run
if env['OURPLATFORM']=='linuxcross': if env['OURPLATFORM']=='linuxcross':

@ -182,7 +182,7 @@ WITH_BF_STATICOCIO = True
WITH_BF_BOOST = True WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost' BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include' BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49' BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49 libboost_wave-vc90-mt-s-1_49'
BF_BOOST_LIB_INTERNATIONAL = 'libboost_locale-vc90-mt-s-1_49' BF_BOOST_LIB_INTERNATIONAL = 'libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib' BF_BOOST_LIBPATH = '${BF_BOOST}/lib'

@ -1,4 +1,4 @@
.TH "BLENDER" "1" "December 04, 2012" "Blender Blender 2\&.65" .TH "BLENDER" "1" "February 14, 2013" "Blender Blender 2\&.66"
.SH NAME .SH NAME
blender \- a 3D modelling and rendering package blender \- a 3D modelling and rendering package
@ -15,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business
http://www.blender.org http://www.blender.org
.SH OPTIONS .SH OPTIONS
Blender 2.65 Blender 2.66
Usage: blender [args ...] [file] [args ...] Usage: blender [args ...] [file] [args ...]
.br .br
.SS "Render Options:" .SS "Render Options:"
@ -218,6 +218,12 @@ Turn debugging on
Enable floating point exceptions Enable floating point exceptions
.br .br
.TP
.B \-\-disable\-crash\-handler
.br
Disable the crash handler
.br
.IP .IP
.TP .TP
@ -301,7 +307,13 @@ Disable automatic python script execution (pydrivers & startup scripts)
.TP .TP
.B \-P or \-\-python <filename> .B \-P or \-\-python <filename>
.br .br
Run the given Python script (filename or Blender Text) Run the given Python script file
.br
.TP
.B \-\-python\-text <name>
.br
Run the given Python script text block
.br .br
.TP .TP
@ -398,6 +410,12 @@ Register .blend extension, then exit (Windows only)
Silently register .blend extension, then exit (Windows only) Silently register .blend extension, then exit (Windows only)
.br .br
.TP
.B \-\-no\-native\-pixels
.br
Do not use native pixel size, for high resolution displays (MacBook 'Retina')
.br
.SS "Argument Parsing:" .SS "Argument Parsing:"
arguments must be separated by white space. eg arguments must be separated by white space. eg

@ -88,7 +88,7 @@ CSG_PerformBooleanOperation(
BoolOpType boolType; BoolOpType boolType;
switch( op_type ) { switch (op_type) {
case e_csg_union: case e_csg_union:
boolType = BOP_UNION; boolType = BOP_UNION;
break; break;

@ -43,6 +43,8 @@ incs = []
defs = [] defs = []
cxxflags = Split(env['CXXFLAGS']) cxxflags = Split(env['CXXFLAGS'])
defs.append('GLEW_STATIC')
defs.append('CCL_NAMESPACE_BEGIN=namespace ccl {') defs.append('CCL_NAMESPACE_BEGIN=namespace ccl {')
defs.append('CCL_NAMESPACE_END=}') defs.append('CCL_NAMESPACE_END=}')

@ -128,7 +128,8 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
height = b_engine.resolution_y(); height = b_engine.resolution_y();
if(scene->params.modified(scene_params) || if(scene->params.modified(scene_params) ||
session->params.modified(session_params)) session->params.modified(session_params) ||
!scene_params.persistent_data)
{ {
/* if scene or session parameters changed, it's easier to simply re-create /* if scene or session parameters changed, it's easier to simply re-create
* them rather than trying to distinguish which settings need to be updated * them rather than trying to distinguish which settings need to be updated
@ -410,7 +411,9 @@ void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::Re
int components = b_pass.channels(); int components = b_pass.channels();
/* copy pixels */ /* copy pixels */
if(buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0])) if(!buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0]))
memset(&pixels[0], 0, pixels.size()*sizeof(float));
b_pass.rect(&pixels[0]); b_pass.rect(&pixels[0]);
} }
} }
@ -517,6 +520,9 @@ bool BlenderSession::draw(int w, int h)
session->reset(buffer_params, session_params.samples); session->reset(buffer_params, session_params.samples);
} }
} }
else {
tag_update();
}
/* update status and progress for 3d view draw */ /* update status and progress for 3d view draw */
update_status_progress(); update_status_progress();

@ -307,7 +307,10 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background)
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits"); params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false; params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false;
params.persistent_images = (background)? r.use_persistent_data(): false; if(background && params.shadingsystem != SceneParams::OSL)
params.persistent_data = r.use_persistent_data();
else
params.persistent_data = false;
return params; return params;
} }

@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN
static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render) static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render)
{ {
return data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1); return data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, true);
} }
static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size) static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size)

@ -30,6 +30,7 @@
#include "util_foreach.h" #include "util_foreach.h"
#include "util_map.h" #include "util_map.h"
#include "util_progress.h" #include "util_progress.h"
#include "util_system.h"
#include "util_types.h" #include "util_types.h"
CCL_NAMESPACE_BEGIN CCL_NAMESPACE_BEGIN
@ -71,6 +72,7 @@ BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects)
bool BVH::cache_read(CacheData& key) bool BVH::cache_read(CacheData& key)
{ {
key.add(system_cpu_bits());
key.add(&params, sizeof(params)); key.add(&params, sizeof(params));
foreach(Object *ob, objects) { foreach(Object *ob, objects) {
@ -340,6 +342,10 @@ void BVH::pack_primitives()
Object *ob = objects[tob]; Object *ob = objects[tob];
pack.prim_visibility[i] = ob->visibility; pack.prim_visibility[i] = ob->visibility;
} }
else {
memset(&pack.tri_woop[i * nsize], 0, sizeof(float4)*3);
pack.prim_visibility[i] = 0;
}
} }
} }
@ -476,7 +482,7 @@ void BVH::pack_instances(size_t nodes_size)
} }
/* merge nodes */ /* merge nodes */
if( bvh->pack.nodes.size()) { if(bvh->pack.nodes.size()) {
size_t nsize_bbox = (use_qbvh)? nsize-2: nsize-1; size_t nsize_bbox = (use_qbvh)? nsize-2: nsize-1;
int4 *bvh_nodes = &bvh->pack.nodes[0]; int4 *bvh_nodes = &bvh->pack.nodes[0];
size_t bvh_nodes_size = bvh->pack.nodes.size(); size_t bvh_nodes_size = bvh->pack.nodes.size();

@ -171,26 +171,7 @@ public:
int end_sample = tile.start_sample + tile.num_samples; int end_sample = tile.start_sample + tile.num_samples;
#ifdef WITH_OPTIMIZED_KERNEL #ifdef WITH_OPTIMIZED_KERNEL
if(system_cpu_support_sse2()) { if(system_cpu_support_sse3()) {
for(int sample = start_sample; sample < end_sample; sample++) {
if (task.get_cancel() || task_pool.cancelled()) {
if(task.need_finish_queue == false)
break;
}
for(int y = tile.y; y < tile.y + tile.h; y++) {
for(int x = tile.x; x < tile.x + tile.w; x++) {
kernel_cpu_sse2_path_trace(&kg, render_buffer, rng_state,
sample, x, y, tile.offset, tile.stride);
}
}
tile.sample = sample + 1;
task.update_progress(tile);
}
}
else if(system_cpu_support_sse3()) {
for(int sample = start_sample; sample < end_sample; sample++) { for(int sample = start_sample; sample < end_sample; sample++) {
if (task.get_cancel() || task_pool.cancelled()) { if (task.get_cancel() || task_pool.cancelled()) {
if(task.need_finish_queue == false) if(task.need_finish_queue == false)
@ -209,6 +190,25 @@ public:
task.update_progress(tile); task.update_progress(tile);
} }
} }
else if(system_cpu_support_sse2()) {
for(int sample = start_sample; sample < end_sample; sample++) {
if (task.get_cancel() || task_pool.cancelled()) {
if(task.need_finish_queue == false)
break;
}
for(int y = tile.y; y < tile.y + tile.h; y++) {
for(int x = tile.x; x < tile.x + tile.w; x++) {
kernel_cpu_sse2_path_trace(&kg, render_buffer, rng_state,
sample, x, y, tile.offset, tile.stride);
}
}
tile.sample = sample + 1;
task.update_progress(tile);
}
}
else else
#endif #endif
{ {
@ -247,18 +247,18 @@ public:
void thread_tonemap(DeviceTask& task) void thread_tonemap(DeviceTask& task)
{ {
#ifdef WITH_OPTIMIZED_KERNEL #ifdef WITH_OPTIMIZED_KERNEL
if(system_cpu_support_sse2()) { if(system_cpu_support_sse3()) {
for(int y = task.y; y < task.y + task.h; y++)
for(int x = task.x; x < task.x + task.w; x++)
kernel_cpu_sse2_tonemap(&kernel_globals, (uchar4*)task.rgba, (float*)task.buffer,
task.sample, task.resolution, x, y, task.offset, task.stride);
}
else if(system_cpu_support_sse3()) {
for(int y = task.y; y < task.y + task.h; y++) for(int y = task.y; y < task.y + task.h; y++)
for(int x = task.x; x < task.x + task.w; x++) for(int x = task.x; x < task.x + task.w; x++)
kernel_cpu_sse3_tonemap(&kernel_globals, (uchar4*)task.rgba, (float*)task.buffer, kernel_cpu_sse3_tonemap(&kernel_globals, (uchar4*)task.rgba, (float*)task.buffer,
task.sample, task.resolution, x, y, task.offset, task.stride); task.sample, task.resolution, x, y, task.offset, task.stride);
} }
else if(system_cpu_support_sse2()) {
for(int y = task.y; y < task.y + task.h; y++)
for(int x = task.x; x < task.x + task.w; x++)
kernel_cpu_sse2_tonemap(&kernel_globals, (uchar4*)task.rgba, (float*)task.buffer,
task.sample, task.resolution, x, y, task.offset, task.stride);
}
else else
#endif #endif
{ {
@ -278,17 +278,17 @@ public:
#endif #endif
#ifdef WITH_OPTIMIZED_KERNEL #ifdef WITH_OPTIMIZED_KERNEL
if(system_cpu_support_sse2()) { if(system_cpu_support_sse3()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_sse2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); kernel_cpu_sse3_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
if(task_pool.cancelled()) if(task_pool.cancelled())
break; break;
} }
} }
else if(system_cpu_support_sse3()) { else if(system_cpu_support_sse2()) {
for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) { for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++) {
kernel_cpu_sse3_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x); kernel_cpu_sse2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output, task.shader_eval_type, x);
if(task_pool.cancelled()) if(task_pool.cancelled())
break; break;

@ -109,11 +109,11 @@ public:
} }
} }
#ifdef NDEBUG /*#ifdef NDEBUG
#define cuda_abort() #define cuda_abort()
#else #else
#define cuda_abort() abort() #define cuda_abort() abort()
#endif #endif*/
#define cuda_assert(stmt) \ #define cuda_assert(stmt) \
{ \ { \
@ -128,19 +128,21 @@ public:
} \ } \
} }
bool cuda_error(CUresult result) bool cuda_error_(CUresult result, const string& stmt)
{ {
if(result == CUDA_SUCCESS) if(result == CUDA_SUCCESS)
return false; return false;
string message = string_printf("CUDA error: %s", cuda_error_string(result)); string message = string_printf("CUDA error at %s: %s", stmt.c_str(), cuda_error_string(result));
if(error_msg == "") if(error_msg == "")
error_msg = message; error_msg = message;
fprintf(stderr, "%s\n", message.c_str()); fprintf(stderr, "%s\n", message.c_str());
return true; return true;
} }
void cuda_error(const string& message) #define cuda_error(stmt) cuda_error_(stmt, #stmt)
void cuda_error_message(const string& message)
{ {
if(error_msg == "") if(error_msg == "")
error_msg = message; error_msg = message;
@ -187,7 +189,7 @@ public:
} }
} }
if(cuda_error(result)) if(cuda_error_(result, "cuCtxCreate"))
return; return;
cuda_pop_context(); cuda_pop_context();
@ -208,7 +210,7 @@ public:
cuDeviceComputeCapability(&major, &minor, cuDevId); cuDeviceComputeCapability(&major, &minor, cuDevId);
if(major <= 1 && minor <= 2) { if(major <= 1 && minor <= 2) {
cuda_error(string_printf("CUDA device supported only with compute capability 1.3 or up, found %d.%d.", major, minor)); cuda_error_message(string_printf("CUDA device supported only with compute capability 1.3 or up, found %d.%d.", major, minor));
return false; return false;
} }
} }
@ -241,9 +243,9 @@ public:
#ifdef _WIN32 #ifdef _WIN32
if(cuHavePrecompiledKernels()) { if(cuHavePrecompiledKernels()) {
if(major <= 1 && minor <= 2) if(major <= 1 && minor <= 2)
cuda_error(string_printf("CUDA device requires compute capability 1.3 or up, found %d.%d. Your GPU is not supported.", major, minor)); cuda_error_message(string_printf("CUDA device requires compute capability 1.3 or up, found %d.%d. Your GPU is not supported.", major, minor));
else else
cuda_error(string_printf("CUDA binary kernel for this graphics card compute capability (%d.%d) not found.", major, minor)); cuda_error_message(string_printf("CUDA binary kernel for this graphics card compute capability (%d.%d) not found.", major, minor));
return ""; return "";
} }
#endif #endif
@ -252,7 +254,7 @@ public:
string nvcc = cuCompilerPath(); string nvcc = cuCompilerPath();
if(nvcc == "") { if(nvcc == "") {
cuda_error("CUDA nvcc compiler not found. Install CUDA toolkit in default location."); cuda_error_message("CUDA nvcc compiler not found. Install CUDA toolkit in default location.");
return ""; return "";
} }
@ -272,13 +274,13 @@ public:
nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), maxreg, include.c_str()); nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), maxreg, include.c_str());
if(system(command.c_str()) == -1) { if(system(command.c_str()) == -1) {
cuda_error("Failed to execute compilation command, see console for details."); cuda_error_message("Failed to execute compilation command, see console for details.");
return ""; return "";
} }
/* verify if compilation succeeded */ /* verify if compilation succeeded */
if(!path_exists(cubin)) { if(!path_exists(cubin)) {
cuda_error("CUDA kernel compilation failed, see console for details."); cuda_error_message("CUDA kernel compilation failed, see console for details.");
return ""; return "";
} }
@ -306,8 +308,8 @@ public:
cuda_push_context(); cuda_push_context();
CUresult result = cuModuleLoad(&cuModule, cubin.c_str()); CUresult result = cuModuleLoad(&cuModule, cubin.c_str());
if(cuda_error(result)) if(cuda_error_(result, "cuModuleLoad"))
cuda_error(string_printf("Failed loading CUDA kernel %s.", cubin.c_str())); cuda_error_message(string_printf("Failed loading CUDA kernel %s.", cubin.c_str()));
cuda_pop_context(); cuda_pop_context();
@ -737,7 +739,7 @@ public:
CUresult result = cuGraphicsGLRegisterBuffer(&pmem.cuPBOresource, pmem.cuPBO, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE); CUresult result = cuGraphicsGLRegisterBuffer(&pmem.cuPBOresource, pmem.cuPBO, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
if(!cuda_error(result)) { if(result == CUDA_SUCCESS) {
cuda_pop_context(); cuda_pop_context();
mem.device_pointer = pmem.cuTexId; mem.device_pointer = pmem.cuTexId;

@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
/* Direction Emission */ /* Direction Emission */
__device float3 direct_emissive_eval(KernelGlobals *kg, float rando, __device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
LightSample *ls, float u, float v, float3 I, float t, float time) LightSample *ls, float u, float v, float3 I, float t, float time)
{ {
/* setup shading at emitter */ /* setup shading at emitter */
@ -74,7 +74,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
return eval; return eval;
} }
__device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, __device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval, float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval,
bool *is_lamp) bool *is_lamp)
{ {
@ -141,14 +141,14 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
} }
/* return if it's a lamp for shadow pass */ /* return if it's a lamp for shadow pass */
*is_lamp = (ls.prim == ~0); *is_lamp = (ls.prim == ~0 && ls.type != LIGHT_BACKGROUND);
return true; return true;
} }
/* Indirect Primitive Emission */ /* Indirect Primitive Emission */
__device float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf) __device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
{ {
/* evaluate emissive closure */ /* evaluate emissive closure */
float3 L = shader_emissive_eval(kg, sd); float3 L = shader_emissive_eval(kg, sd);
@ -171,7 +171,7 @@ __device float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, f
/* Indirect Lamp Emission */ /* Indirect Lamp Emission */
__device bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission) __device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission)
{ {
LightSample ls; LightSample ls;
int lamp = lamp_light_eval_sample(kg, randt); int lamp = lamp_light_eval_sample(kg, randt);
@ -200,7 +200,7 @@ __device bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag,
/* Indirect Background */ /* Indirect Background */
__device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf) __device_noinline float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf)
{ {
#ifdef __BACKGROUND__ #ifdef __BACKGROUND__
/* evaluate background closure */ /* evaluate background closure */

@ -454,7 +454,7 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
ls->lamp = ~0; ls->lamp = ~0;
ls->shader |= SHADER_USE_MIS; ls->shader |= SHADER_USE_MIS;
ls->t = 0.0f; ls->t = 0.0f;
ls->type = LIGHT_AREA; ls->type = LIGHT_TRIANGLE;
ls->eval_fac = 1.0f; ls->eval_fac = 1.0f;
object_transform_light_sample(kg, ls, object, time); object_transform_light_sample(kg, ls, object, time);

@ -125,14 +125,7 @@ __device_inline void kernel_write_light_passes(KernelGlobals *kg, __global float
kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, sample, L->color_transmission); kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, sample, L->color_transmission);
if(flag & PASS_SHADOW) { if(flag & PASS_SHADOW) {
float4 shadow = L->shadow; float4 shadow = L->shadow;
shadow.w = kernel_data.film.pass_shadow_scale;
/* bit of an ugly hack to compensate for emitting triangles influencing
* amount of samples we get for this pass */
if(kernel_data.integrator.progressive && kernel_data.integrator.pdf_triangles != 0.0f)
shadow.w = 0.5f;
else
shadow.w = 1.0f;
kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, sample, shadow); kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, sample, shadow);
} }
#endif #endif

@ -53,7 +53,7 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD
} }
#endif #endif
__device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, __device_noinline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
const Intersection *isect, const Ray *ray) const Intersection *isect, const Ray *ray)
{ {
#ifdef __INSTANCING__ #ifdef __INSTANCING__
@ -160,7 +160,7 @@ __device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
/* ShaderData setup from position sampled on mesh */ /* ShaderData setup from position sampled on mesh */
__device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, __device_noinline void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
const float3 P, const float3 Ng, const float3 I, const float3 P, const float3 Ng, const float3 I,
int shader, int object, int prim, float u, float v, float t, float time, int segment = ~0) int shader, int object, int prim, float u, float v, float t, float time, int segment = ~0)
{ {
@ -283,7 +283,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
/* ShaderData setup for displacement */ /* ShaderData setup for displacement */
__device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd, __device_noinline void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
int object, int prim, float u, float v) int object, int prim, float u, float v)
{ {
/* Note: no OSLShader::init call here, this is done in shader_setup_from_sample! */ /* Note: no OSLShader::init call here, this is done in shader_setup_from_sample! */

@ -299,6 +299,7 @@ typedef enum LightType {
LIGHT_AREA, LIGHT_AREA,
LIGHT_AO, LIGHT_AO,
LIGHT_SPOT, LIGHT_SPOT,
LIGHT_TRIANGLE,
LIGHT_STRAND LIGHT_STRAND
} LightType; } LightType;
@ -609,9 +610,9 @@ typedef struct KernelFilm {
int pass_ao; int pass_ao;
int pass_shadow; int pass_shadow;
float pass_shadow_scale;
int pass_pad1; int pass_pad1;
int pass_pad2; int pass_pad2;
int pass_pad3;
} KernelFilm; } KernelFilm;
typedef struct KernelBackground { typedef struct KernelBackground {

@ -83,6 +83,7 @@ RenderTile::RenderTile()
w = 0; w = 0;
h = 0; h = 0;
sample = 0;
start_sample = 0; start_sample = 0;
num_samples = 0; num_samples = 0;
resolution = 0; resolution = 0;

@ -85,9 +85,10 @@ bool ImageManager::set_animation_frame_update(int frame)
return false; return false;
} }
bool ImageManager::is_float_image(const string& filename, void *builtin_data) bool ImageManager::is_float_image(const string& filename, void *builtin_data, bool& is_linear)
{ {
bool is_float = false; bool is_float = false;
is_linear = false;
if(builtin_data) { if(builtin_data) {
if(builtin_image_info_cb) { if(builtin_image_info_cb) {
@ -95,6 +96,9 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data)
builtin_image_info_cb(filename, builtin_data, is_float, width, height, channels); builtin_image_info_cb(filename, builtin_data, is_float, width, height, channels);
} }
if(is_float)
is_linear = true;
return is_float; return is_float;
} }
@ -106,13 +110,29 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data)
if(in->open(filename, spec)) { if(in->open(filename, spec)) {
/* check the main format, and channel formats; /* check the main format, and channel formats;
* if any take up more than one byte, we'll need a float texture slot */ * if any take up more than one byte, we'll need a float texture slot */
if(spec.format.basesize() > 1) if(spec.format.basesize() > 1) {
is_float = true; is_float = true;
is_linear = true;
}
for(size_t channel = 0; channel < spec.channelformats.size(); channel++) { for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
if(spec.channelformats[channel].basesize() > 1) if(spec.channelformats[channel].basesize() > 1) {
is_float = true; is_float = true;
is_linear = true;
} }
}
/* basic color space detection, not great but better than nothing
* before we do OpenColorIO integration */
if(is_float) {
string colorspace = spec.get_string_attribute("oiio:ColorSpace");
is_linear = !(colorspace == "sRGB" ||
colorspace == "GammaCorrected" ||
strcmp(in->format_name(), "png") == 0);
}
else
is_linear = false;
in->close(); in->close();
} }
@ -123,13 +143,13 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data)
return is_float; return is_float;
} }
int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float) int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear)
{ {
Image *img; Image *img;
size_t slot; size_t slot;
/* load image info and find out if we need a float texture */ /* load image info and find out if we need a float texture */
is_float = (pack_images)? false: is_float_image(filename, builtin_data); is_float = (pack_images)? false: is_float_image(filename, builtin_data, is_linear);
if(is_float) { if(is_float) {
/* find existing image */ /* find existing image */

@ -51,9 +51,9 @@ public:
ImageManager(); ImageManager();
~ImageManager(); ~ImageManager();
int add_image(const string& filename, void *builtin_data, bool animated, bool& is_float); int add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear);
void remove_image(const string& filename, void *builtin_data); void remove_image(const string& filename, void *builtin_data);
bool is_float_image(const string& filename, void *builtin_data); bool is_float_image(const string& filename, void *builtin_data, bool& is_linear);
void device_update(Device *device, DeviceScene *dscene, Progress& progress); void device_update(Device *device, DeviceScene *dscene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene); void device_free(Device *device, DeviceScene *dscene);

@ -143,6 +143,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* count */ /* count */
size_t num_lights = scene->lights.size(); size_t num_lights = scene->lights.size();
size_t num_background_lights = 0;
size_t num_triangles = 0; size_t num_triangles = 0;
size_t num_curve_segments = 0; size_t num_curve_segments = 0;
@ -306,6 +307,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
if(light->size > 0.0f && light->use_mis) if(light->size > 0.0f && light->use_mis)
use_lamp_mis = true; use_lamp_mis = true;
if(light->type == LIGHT_BACKGROUND)
num_background_lights++;
} }
/* normalize cumulative distribution functions */ /* normalize cumulative distribution functions */
@ -324,6 +327,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* update device */ /* update device */
KernelIntegrator *kintegrator = &dscene->data.integrator; KernelIntegrator *kintegrator = &dscene->data.integrator;
KernelFilm *kfilm = &dscene->data.film;
kintegrator->use_direct_light = (totarea > 0.0f); kintegrator->use_direct_light = (totarea > 0.0f);
if(kintegrator->use_direct_light) { if(kintegrator->use_direct_light) {
@ -354,6 +358,16 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->use_lamp_mis = use_lamp_mis; kintegrator->use_lamp_mis = use_lamp_mis;
/* bit of an ugly hack to compensate for emitting triangles influencing
* amount of samples we get for this pass */
if(scene->integrator->progressive && kintegrator->pdf_triangles != 0.0f)
kfilm->pass_shadow_scale = 0.5f;
else
kfilm->pass_shadow_scale = 1.0f;
if(num_background_lights < num_lights)
kfilm->pass_shadow_scale *= (float)(num_lights - num_background_lights)/(float)num_lights;
/* CDF */ /* CDF */
device->tex_alloc("__light_distribution", dscene->light_distribution); device->tex_alloc("__light_distribution", dscene->light_distribution);
} }
@ -366,6 +380,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->pdf_lights = 0.0f; kintegrator->pdf_lights = 0.0f;
kintegrator->inv_pdf_lights = 0.0f; kintegrator->inv_pdf_lights = 0.0f;
kintegrator->use_lamp_mis = false; kintegrator->use_lamp_mis = false;
kfilm->pass_shadow_scale = 1.0f;
} }
} }

@ -966,6 +966,16 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
dscene->attributes_map.clear(); dscene->attributes_map.clear();
dscene->attributes_float.clear(); dscene->attributes_float.clear();
dscene->attributes_float3.clear(); dscene->attributes_float3.clear();
#ifdef WITH_OSL
OSLGlobals *og = (OSLGlobals*)device->osl_memory();
if(og) {
og->object_name_map.clear();
og->attribute_map.clear();
og->object_names.clear();
}
#endif
} }
void MeshManager::tag_update(Scene *scene) void MeshManager::tag_update(Scene *scene)

@ -141,6 +141,7 @@ ImageTextureNode::ImageTextureNode()
image_manager = NULL; image_manager = NULL;
slot = -1; slot = -1;
is_float = -1; is_float = -1;
is_linear = false;
filename = ""; filename = "";
builtin_data = NULL; builtin_data = NULL;
color_space = ustring("Color"); color_space = ustring("Color");
@ -165,6 +166,7 @@ ShaderNode *ImageTextureNode::clone() const
node->image_manager = NULL; node->image_manager = NULL;
node->slot = -1; node->slot = -1;
node->is_float = -1; node->is_float = -1;
node->is_linear = false;
return node; return node;
} }
@ -177,7 +179,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager; image_manager = compiler.image_manager;
if(is_float == -1) { if(is_float == -1) {
bool is_float_bool; bool is_float_bool;
slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool); slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear);
is_float = (int)is_float_bool; is_float = (int)is_float_bool;
} }
@ -189,7 +191,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
if(slot != -1) { if(slot != -1) {
compiler.stack_assign(vector_in); compiler.stack_assign(vector_in);
int srgb = (is_float || color_space != "Color")? 0: 1; int srgb = (is_linear || color_space != "Color")? 0: 1;
int vector_offset = vector_in->stack_offset; int vector_offset = vector_in->stack_offset;
if(!tex_mapping.skip()) { if(!tex_mapping.skip()) {
@ -238,10 +240,10 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
tex_mapping.compile(compiler); tex_mapping.compile(compiler);
if(is_float == -1) if(is_float == -1)
is_float = (int)image_manager->is_float_image(filename, NULL); is_float = (int)image_manager->is_float_image(filename, NULL, is_linear);
compiler.parameter("filename", filename.c_str()); compiler.parameter("filename", filename.c_str());
if(is_float || color_space != "Color") if(is_linear || color_space != "Color")
compiler.parameter("color_space", "Linear"); compiler.parameter("color_space", "Linear");
else else
compiler.parameter("color_space", "sRGB"); compiler.parameter("color_space", "sRGB");
@ -271,6 +273,7 @@ EnvironmentTextureNode::EnvironmentTextureNode()
image_manager = NULL; image_manager = NULL;
slot = -1; slot = -1;
is_float = -1; is_float = -1;
is_linear = false;
filename = ""; filename = "";
builtin_data = NULL; builtin_data = NULL;
color_space = ustring("Color"); color_space = ustring("Color");
@ -294,6 +297,7 @@ ShaderNode *EnvironmentTextureNode::clone() const
node->image_manager = NULL; node->image_manager = NULL;
node->slot = -1; node->slot = -1;
node->is_float = -1; node->is_float = -1;
node->is_linear = false;
return node; return node;
} }
@ -306,7 +310,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager; image_manager = compiler.image_manager;
if(slot == -1) { if(slot == -1) {
bool is_float_bool; bool is_float_bool;
slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool); slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear);
is_float = (int)is_float_bool; is_float = (int)is_float_bool;
} }
@ -318,7 +322,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
if(slot != -1) { if(slot != -1) {
compiler.stack_assign(vector_in); compiler.stack_assign(vector_in);
int srgb = (is_float || color_space != "Color")? 0: 1; int srgb = (is_linear || color_space != "Color")? 0: 1;
int vector_offset = vector_in->stack_offset; int vector_offset = vector_in->stack_offset;
if(!tex_mapping.skip()) { if(!tex_mapping.skip()) {
@ -356,11 +360,11 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler)
tex_mapping.compile(compiler); tex_mapping.compile(compiler);
if(is_float == -1) if(is_float == -1)
is_float = (int)image_manager->is_float_image(filename, NULL); is_float = (int)image_manager->is_float_image(filename, NULL, is_linear);
compiler.parameter("filename", filename.c_str()); compiler.parameter("filename", filename.c_str());
compiler.parameter("projection", projection); compiler.parameter("projection", projection);
if(is_float || color_space != "Color") if(is_linear || color_space != "Color")
compiler.parameter("color_space", "Linear"); compiler.parameter("color_space", "Linear");
else else
compiler.parameter("color_space", "sRGB"); compiler.parameter("color_space", "sRGB");

@ -69,6 +69,7 @@ public:
ImageManager *image_manager; ImageManager *image_manager;
int slot; int slot;
int is_float; int is_float;
bool is_linear;
string filename; string filename;
void *builtin_data; void *builtin_data;
ustring color_space; ustring color_space;
@ -89,6 +90,7 @@ public:
ImageManager *image_manager; ImageManager *image_manager;
int slot; int slot;
int is_float; int is_float;
bool is_linear;
string filename; string filename;
void *builtin_data; void *builtin_data;
ustring color_space; ustring color_space;

@ -47,17 +47,27 @@ OSLShaderManager::OSLShaderManager()
{ {
services = new OSLRenderServices(); services = new OSLRenderServices();
shading_system_init();
texture_system_init(); texture_system_init();
shading_system_init();
} }
OSLShaderManager::~OSLShaderManager() OSLShaderManager::~OSLShaderManager()
{ {
OSL::ShadingSystem::destroy(ss); OSL::ShadingSystem::destroy(ss);
OSL::TextureSystem::destroy(ts); OSL::TextureSystem::destroy(ts);
delete services; delete services;
} }
void OSLShaderManager::reset(Scene *scene)
{
OSL::ShadingSystem::destroy(ss);
delete services;
services = new OSLRenderServices();
shading_system_init();
}
void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{ {
if(!need_update) if(!need_update)
@ -88,6 +98,7 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
og->ss = ss; og->ss = ss;
og->ts = ts; og->ts = ts;
og->services = services; og->services = services;
int background_id = scene->shader_manager->get_shader_id(scene->default_background); int background_id = scene->shader_manager->get_shader_id(scene->default_background);
og->background_state = og->surface_state[background_id & SHADER_MASK]; og->background_state = og->surface_state[background_id & SHADER_MASK];
og->use = true; og->use = true;

@ -36,7 +36,7 @@ class Device;
class DeviceScene; class DeviceScene;
class ImageManager; class ImageManager;
class OSLRenderServices; class OSLRenderServices;
class OSLGlobals; struct OSLGlobals;
class Scene; class Scene;
class ShaderGraph; class ShaderGraph;
class ShaderNode; class ShaderNode;
@ -64,6 +64,8 @@ public:
OSLShaderManager(); OSLShaderManager();
~OSLShaderManager(); ~OSLShaderManager();
void reset(Scene *scene);
bool use_osl() { return true; } bool use_osl() { return true; }
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);

@ -85,6 +85,12 @@ void Scene::free_memory(bool final)
foreach(ParticleSystem *p, particle_systems) foreach(ParticleSystem *p, particle_systems)
delete p; delete p;
shaders.clear();
meshes.clear();
objects.clear();
lights.clear();
particle_systems.clear();
if(device) { if(device) {
camera->device_free(device, &dscene); camera->device_free(device, &dscene);
filter->device_free(device, &dscene); filter->device_free(device, &dscene);
@ -100,7 +106,7 @@ void Scene::free_memory(bool final)
particle_system_manager->device_free(device, &dscene); particle_system_manager->device_free(device, &dscene);
curve_system_manager->device_free(device, &dscene); curve_system_manager->device_free(device, &dscene);
if(!params.persistent_images || final) if(!params.persistent_data || final)
image_manager->device_free(device, &dscene); image_manager->device_free(device, &dscene);
} }
@ -118,13 +124,6 @@ void Scene::free_memory(bool final)
delete curve_system_manager; delete curve_system_manager;
delete image_manager; delete image_manager;
} }
else {
shaders.clear();
meshes.clear();
objects.clear();
lights.clear();
particle_systems.clear();
}
} }
void Scene::device_update(Device *device_, Progress& progress) void Scene::device_update(Device *device_, Progress& progress)
@ -257,6 +256,7 @@ bool Scene::need_reset()
void Scene::reset() void Scene::reset()
{ {
shader_manager->reset(this);
shader_manager->add_default(this); shader_manager->add_default(this);
/* ensure all objects are updated */ /* ensure all objects are updated */

@ -125,7 +125,7 @@ public:
bool use_bvh_cache; bool use_bvh_cache;
bool use_bvh_spatial_split; bool use_bvh_spatial_split;
bool use_qbvh; bool use_qbvh;
bool persistent_images; bool persistent_data;
SceneParams() SceneParams()
{ {
@ -146,7 +146,7 @@ public:
&& use_bvh_cache == params.use_bvh_cache && use_bvh_cache == params.use_bvh_cache
&& use_bvh_spatial_split == params.use_bvh_spatial_split && use_bvh_spatial_split == params.use_bvh_spatial_split
&& use_qbvh == params.use_qbvh && use_qbvh == params.use_qbvh
&& persistent_images == params.persistent_images); } && persistent_data == params.persistent_data); }
}; };
/* Scene */ /* Scene */

@ -132,6 +132,8 @@ bool Session::ready_to_reset()
void Session::reset_gpu(BufferParams& buffer_params, int samples) void Session::reset_gpu(BufferParams& buffer_params, int samples)
{ {
thread_scoped_lock pause_lock(pause_mutex);
/* block for buffer acces and reset immediately. we can't do this /* block for buffer acces and reset immediately. we can't do this
* in the thread, because we need to allocate an OpenGL buffer, and * in the thread, because we need to allocate an OpenGL buffer, and
* that only works in the main thread */ * that only works in the main thread */
@ -208,7 +210,12 @@ void Session::run_gpu()
* wait for pause condition notify to wake up again */ * wait for pause condition notify to wake up again */
thread_scoped_lock pause_lock(pause_mutex); thread_scoped_lock pause_lock(pause_mutex);
if(pause || no_tiles) { if(!pause && !tile_manager.done()) {
/* reset could have happened after no_tiles was set, before this lock.
* in this case we shall not wait for pause condition
*/
}
else if(pause || no_tiles) {
update_status_time(pause, no_tiles); update_status_time(pause, no_tiles);
while(1) { while(1) {
@ -295,6 +302,7 @@ void Session::run_gpu()
void Session::reset_cpu(BufferParams& buffer_params, int samples) void Session::reset_cpu(BufferParams& buffer_params, int samples)
{ {
thread_scoped_lock reset_lock(delayed_reset.mutex); thread_scoped_lock reset_lock(delayed_reset.mutex);
thread_scoped_lock pause_lock(pause_mutex);
display_outdated = true; display_outdated = true;
reset_time = time_dt(); reset_time = time_dt();
@ -484,7 +492,16 @@ void Session::run_cpu()
* wait for pause condition notify to wake up again */ * wait for pause condition notify to wake up again */
thread_scoped_lock pause_lock(pause_mutex); thread_scoped_lock pause_lock(pause_mutex);
if(pause || no_tiles) { if(!pause && delayed_reset.do_reset) {
/* reset once to start */
thread_scoped_lock reset_lock(delayed_reset.mutex);
thread_scoped_lock buffers_lock(buffers_mutex);
thread_scoped_lock display_lock(display_mutex);
reset_(delayed_reset.params, delayed_reset.samples);
delayed_reset.do_reset = false;
}
else if(pause || no_tiles) {
update_status_time(pause, no_tiles); update_status_time(pause, no_tiles);
while(1) { while(1) {

@ -110,6 +110,8 @@ public:
static ShaderManager *create(Scene *scene, int shadingsystem); static ShaderManager *create(Scene *scene, int shadingsystem);
virtual ~ShaderManager(); virtual ~ShaderManager();
virtual void reset(Scene *scene) = 0;
virtual bool use_osl() { return false; } virtual bool use_osl() { return false; }
/* device update */ /* device update */

@ -40,6 +40,10 @@ SVMShaderManager::~SVMShaderManager()
{ {
} }
void SVMShaderManager::reset(Scene *scene)
{
}
void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{ {
if(!need_update) if(!need_update)

@ -45,6 +45,8 @@ public:
SVMShaderManager(); SVMShaderManager();
~SVMShaderManager(); ~SVMShaderManager();
void reset(Scene *scene);
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene); void device_free(Device *device, DeviceScene *dscene);
}; };

@ -61,15 +61,17 @@ public:
__forceinline void grow(const float3& pt) __forceinline void grow(const float3& pt)
{ {
min = ccl::min(min, pt); /* the order of arguments to min is such that if pt is nan, it will not
max = ccl::max(max, pt); * influence the resulting bounding box */
min = ccl::min(pt, min);
max = ccl::max(pt, max);
} }
__forceinline void grow(const float3& pt, float border) __forceinline void grow(const float3& pt, float border)
{ {
float3 shift = {border, border, border, 0.0f}; float3 shift = {border, border, border, 0.0f};
min = ccl::min(min, pt - shift); min = ccl::min(pt - shift, min);
max = ccl::max(max, pt + shift); max = ccl::max(pt + shift, max);
} }
__forceinline void grow(const BoundBox& bbox) __forceinline void grow(const BoundBox& bbox)

@ -72,7 +72,7 @@ public:
buffers.push_back(buffer); buffers.push_back(buffer);
} }
void add(void *data, size_t size) void add(const void *data, size_t size)
{ {
if(size) { if(size) {
CacheBuffer buffer(data, size); CacheBuffer buffer(data, size);
@ -80,19 +80,19 @@ public:
} }
} }
void add(int& data) void add(const int& data)
{ {
CacheBuffer buffer(&data, sizeof(int)); CacheBuffer buffer(&data, sizeof(int));
buffers.push_back(buffer); buffers.push_back(buffer);
} }
void add(float& data) void add(const float& data)
{ {
CacheBuffer buffer(&data, sizeof(float)); CacheBuffer buffer(&data, sizeof(float));
buffers.push_back(buffer); buffers.push_back(buffer);
} }
void add(size_t& data) void add(const size_t& data)
{ {
CacheBuffer buffer(&data, sizeof(size_t)); CacheBuffer buffer(&data, sizeof(size_t));
buffers.push_back(buffer); buffers.push_back(buffer);

@ -1028,8 +1028,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
if (!validWindow(window)) { if (!validWindow(window)) {
return GHOST_kFailure; return GHOST_kFailure;
} }
switch(eventType) switch (eventType) {
{
case GHOST_kEventWindowClose: case GHOST_kEventWindowClose:
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) ); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
break; break;
@ -1086,8 +1085,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
if (!validWindow(window)) { if (!validWindow(window)) {
return GHOST_kFailure; return GHOST_kFailure;
} }
switch(eventType) switch (eventType) {
{
case GHOST_kEventDraggingEntered: case GHOST_kEventDraggingEntered:
case GHOST_kEventDraggingUpdated: case GHOST_kEventDraggingUpdated:
case GHOST_kEventDraggingExited: case GHOST_kEventDraggingExited:

@ -109,33 +109,38 @@ GHOST_SystemX11(
m_xim = NULL; m_xim = NULL;
#endif #endif
m_delete_window_atom #define GHOST_INTERN_ATOM_IF_EXISTS(atom) { m_atom.atom = XInternAtom(m_display, #atom , True); } (void)0
= XInternAtom(m_display, "WM_DELETE_WINDOW", True); #define GHOST_INTERN_ATOM(atom) { m_atom.atom = XInternAtom(m_display, #atom , False); } (void)0
GHOST_INTERN_ATOM_IF_EXISTS(WM_DELETE_WINDOW);
GHOST_INTERN_ATOM(WM_PROTOCOLS);
GHOST_INTERN_ATOM(WM_TAKE_FOCUS);
GHOST_INTERN_ATOM(WM_STATE);
GHOST_INTERN_ATOM(WM_CHANGE_STATE);
GHOST_INTERN_ATOM(_NET_WM_STATE);
GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
GHOST_INTERN_ATOM(_NET_WM_STATE_FULLSCREEN);
GHOST_INTERN_ATOM(_MOTIF_WM_HINTS);
GHOST_INTERN_ATOM(TARGETS);
GHOST_INTERN_ATOM(STRING);
GHOST_INTERN_ATOM(COMPOUND_TEXT);
GHOST_INTERN_ATOM(TEXT);
GHOST_INTERN_ATOM(CLIPBOARD);
GHOST_INTERN_ATOM(PRIMARY);
GHOST_INTERN_ATOM(XCLIP_OUT);
GHOST_INTERN_ATOM(INCR);
GHOST_INTERN_ATOM(UTF8_STRING);
#ifdef WITH_X11_XINPUT
m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False);
#endif
#undef GHOST_INTERN_ATOM_IF_EXISTS
#undef GHOST_INTERN_ATOM
m_wm_protocols = XInternAtom(m_display, "WM_PROTOCOLS", False);
m_wm_take_focus = XInternAtom(m_display, "WM_TAKE_FOCUS", False);
m_wm_state = XInternAtom(m_display, "WM_STATE", False);
m_wm_change_state = XInternAtom(m_display, "WM_CHANGE_STATE", False);
m_net_state = XInternAtom(m_display, "_NET_WM_STATE", False);
m_net_max_horz = XInternAtom(m_display,
"_NET_WM_STATE_MAXIMIZED_HORZ", False);
m_net_max_vert = XInternAtom(m_display,
"_NET_WM_STATE_MAXIMIZED_VERT", False);
m_net_fullscreen = XInternAtom(m_display,
"_NET_WM_STATE_FULLSCREEN", False);
m_motif = XInternAtom(m_display, "_MOTIF_WM_HINTS", False);
m_targets = XInternAtom(m_display, "TARGETS", False);
m_string = XInternAtom(m_display, "STRING", False);
m_compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
m_text = XInternAtom(m_display, "TEXT", False);
m_clipboard = XInternAtom(m_display, "CLIPBOARD", False);
m_primary = XInternAtom(m_display, "PRIMARY", False);
m_xclip_out = XInternAtom(m_display, "XCLIP_OUT", False);
m_incr = XInternAtom(m_display, "INCR", False);
m_utf8_string = XInternAtom(m_display, "UTF8_STRING", False);
m_last_warp = 0; m_last_warp = 0;
/* compute the initial time */ /* compute the initial time */
timeval tv; timeval tv;
if (gettimeofday(&tv, NULL) == -1) { if (gettimeofday(&tv, NULL) == -1) {
@ -959,7 +964,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{ {
XClientMessageEvent & xcme = xe->xclient; XClientMessageEvent & xcme = xe->xclient;
if (((Atom)xcme.data.l[0]) == m_delete_window_atom) { if (((Atom)xcme.data.l[0]) == m_atom.WM_DELETE_WINDOW) {
g_event = new g_event = new
GHOST_Event( GHOST_Event(
getMilliSeconds(), getMilliSeconds(),
@ -967,7 +972,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
window window
); );
} }
else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) { else if (((Atom)xcme.data.l[0]) == m_atom.WM_TAKE_FOCUS) {
XWindowAttributes attr; XWindowAttributes attr;
Window fwin; Window fwin;
int revert_to; int revert_to;
@ -1520,7 +1525,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
} }
/* Send a selection request */ /* Send a selection request */
XConvertSelection(m_display, sel, target, m_xclip_out, win, CurrentTime); XConvertSelection(m_display, sel, target, m_atom.XCLIP_OUT, win, CurrentTime);
*context = XCLIB_XCOUT_SENTCONVSEL; *context = XCLIB_XCOUT_SENTCONVSEL;
return; return;
@ -1528,28 +1533,28 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
if (evt.type != SelectionNotify) if (evt.type != SelectionNotify)
return; return;
if (target == m_utf8_string && evt.xselection.property == None) { if (target == m_atom.UTF8_STRING && evt.xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_UTF8; *context = XCLIB_XCOUT_FALLBACK_UTF8;
return; return;
} }
else if (target == m_compound_text && evt.xselection.property == None) { else if (target == m_atom.COMPOUND_TEXT && evt.xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_COMP; *context = XCLIB_XCOUT_FALLBACK_COMP;
return; return;
} }
else if (target == m_text && evt.xselection.property == None) { else if (target == m_atom.TEXT && evt.xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_TEXT; *context = XCLIB_XCOUT_FALLBACK_TEXT;
return; return;
} }
/* find the size and format of the data in property */ /* find the size and format of the data in property */
XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False, XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
AnyPropertyType, &pty_type, &pty_format, AnyPropertyType, &pty_type, &pty_format,
&pty_items, &pty_size, &buffer); &pty_items, &pty_size, &buffer);
XFree(buffer); XFree(buffer);
if (pty_type == m_incr) { if (pty_type == m_atom.INCR) {
/* start INCR mechanism by deleting property */ /* start INCR mechanism by deleting property */
XDeleteProperty(m_display, win, m_xclip_out); XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
XFlush(m_display); XFlush(m_display);
*context = XCLIB_XCOUT_INCR; *context = XCLIB_XCOUT_INCR;
return; return;
@ -1564,12 +1569,12 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
} }
// not using INCR mechanism, just read the property // not using INCR mechanism, just read the property
XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size, XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
False, AnyPropertyType, &pty_type, False, AnyPropertyType, &pty_type,
&pty_format, &pty_items, &pty_size, &buffer); &pty_format, &pty_items, &pty_size, &buffer);
/* finished with property, delete it */ /* finished with property, delete it */
XDeleteProperty(m_display, win, m_xclip_out); XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
/* copy the buffer to the pointer for returned data */ /* copy the buffer to the pointer for returned data */
ltxt = (unsigned char *) malloc(pty_items); ltxt = (unsigned char *) malloc(pty_items);
@ -1602,7 +1607,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
return; return;
/* check size and format of the property */ /* check size and format of the property */
XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False, XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
AnyPropertyType, &pty_type, &pty_format, AnyPropertyType, &pty_type, &pty_format,
&pty_items, &pty_size, &buffer); &pty_items, &pty_size, &buffer);
@ -1611,14 +1616,14 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
* to tell the other X client that we have read * to tell the other X client that we have read
* it and to send the next property */ * it and to send the next property */
XFree(buffer); XFree(buffer);
XDeleteProperty(m_display, win, m_xclip_out); XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
return; return;
} }
if (pty_size == 0) { if (pty_size == 0) {
/* no more data, exit from loop */ /* no more data, exit from loop */
XFree(buffer); XFree(buffer);
XDeleteProperty(m_display, win, m_xclip_out); XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
*context = XCLIB_XCOUT_NONE; *context = XCLIB_XCOUT_NONE;
/* this means that an INCR transfer is now /* this means that an INCR transfer is now
@ -1630,7 +1635,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
/* if we have come this far, the property contains /* if we have come this far, the property contains
* text, we know the size. */ * text, we know the size. */
XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size, XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
False, AnyPropertyType, &pty_type, &pty_format, False, AnyPropertyType, &pty_type, &pty_format,
&pty_items, &pty_size, &buffer); &pty_items, &pty_size, &buffer);
@ -1651,7 +1656,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
XFree(buffer); XFree(buffer);
/* delete property to get the next item */ /* delete property to get the next item */
XDeleteProperty(m_display, win, m_xclip_out); XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
XFlush(m_display); XFlush(m_display);
return; return;
} }
@ -1661,7 +1666,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
{ {
Atom sseln; Atom sseln;
Atom target = m_utf8_string; Atom target = m_atom.UTF8_STRING;
Window owner; Window owner;
/* from xclip.c doOut() v0.11 */ /* from xclip.c doOut() v0.11 */
@ -1671,9 +1676,9 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
unsigned int context = XCLIB_XCOUT_NONE; unsigned int context = XCLIB_XCOUT_NONE;
if (selection == True) if (selection == True)
sseln = m_primary; sseln = m_atom.PRIMARY;
else else
sseln = m_clipboard; sseln = m_atom.CLIPBOARD;
vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows(); vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
vector<GHOST_IWindow *>::iterator win_it = win_vec.begin(); vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
@ -1683,7 +1688,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
/* check if we are the owner. */ /* check if we are the owner. */
owner = XGetSelectionOwner(m_display, sseln); owner = XGetSelectionOwner(m_display, sseln);
if (owner == win) { if (owner == win) {
if (sseln == m_clipboard) { if (sseln == m_atom.CLIPBOARD) {
sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1); sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1);
strcpy((char *)sel_buf, txt_cut_buffer); strcpy((char *)sel_buf, txt_cut_buffer);
return sel_buf; return sel_buf;
@ -1708,19 +1713,19 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
/* fallback is needed. set XA_STRING to target and restart the loop. */ /* fallback is needed. set XA_STRING to target and restart the loop. */
if (context == XCLIB_XCOUT_FALLBACK) { if (context == XCLIB_XCOUT_FALLBACK) {
context = XCLIB_XCOUT_NONE; context = XCLIB_XCOUT_NONE;
target = m_string; target = m_atom.STRING;
continue; continue;
} }
else if (context == XCLIB_XCOUT_FALLBACK_UTF8) { else if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
/* utf8 fail, move to compouned text. */ /* utf8 fail, move to compouned text. */
context = XCLIB_XCOUT_NONE; context = XCLIB_XCOUT_NONE;
target = m_compound_text; target = m_atom.COMPOUND_TEXT;
continue; continue;
} }
else if (context == XCLIB_XCOUT_FALLBACK_COMP) { else if (context == XCLIB_XCOUT_FALLBACK_COMP) {
/* compouned text faile, move to text. */ /* compouned text faile, move to text. */
context = XCLIB_XCOUT_NONE; context = XCLIB_XCOUT_NONE;
target = m_text; target = m_atom.TEXT;
continue; continue;
} }
@ -1737,7 +1742,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
memcpy((char *)tmp_data, (char *)sel_buf, sel_len); memcpy((char *)tmp_data, (char *)sel_buf, sel_len);
tmp_data[sel_len] = '\0'; tmp_data[sel_len] = '\0';
if (sseln == m_string) if (sseln == m_atom.STRING)
XFree(sel_buf); XFree(sel_buf);
else else
free(sel_buf); free(sel_buf);
@ -1758,8 +1763,8 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
if (buffer) { if (buffer) {
if (selection == False) { if (selection == False) {
XSetSelectionOwner(m_display, m_clipboard, m_window, CurrentTime); XSetSelectionOwner(m_display, m_atom.CLIPBOARD, m_window, CurrentTime);
owner = XGetSelectionOwner(m_display, m_clipboard); owner = XGetSelectionOwner(m_display, m_atom.CLIPBOARD);
if (txt_cut_buffer) if (txt_cut_buffer)
free((void *)txt_cut_buffer); free((void *)txt_cut_buffer);
@ -1767,8 +1772,8 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
strcpy(txt_cut_buffer, buffer); strcpy(txt_cut_buffer, buffer);
} }
else { else {
XSetSelectionOwner(m_display, m_primary, m_window, CurrentTime); XSetSelectionOwner(m_display, m_atom.PRIMARY, m_window, CurrentTime);
owner = XGetSelectionOwner(m_display, m_primary); owner = XGetSelectionOwner(m_display, m_atom.PRIMARY);
if (txt_select_buffer) if (txt_select_buffer)
free((void *)txt_select_buffer); free((void *)txt_select_buffer);
@ -1939,7 +1944,9 @@ void GHOST_SystemX11::initXInputDevices()
// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i); // printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
if (m_xtablet.StylusDevice == NULL && is_stylus(device_info[i].name, device_type)) { if ((m_xtablet.StylusDevice == NULL) &&
(is_stylus(device_info[i].name, device_type) || (device_info[i].type == m_atom.TABLET)))
{
// printf("\tfound stylus\n"); // printf("\tfound stylus\n");
m_xtablet.StylusID = device_info[i].id; m_xtablet.StylusID = device_info[i].id;
m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID); m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
@ -1953,10 +1960,17 @@ void GHOST_SystemX11::initXInputDevices()
XValuatorInfo *xvi = (XValuatorInfo *)ici; XValuatorInfo *xvi = (XValuatorInfo *)ici;
m_xtablet.PressureLevels = xvi->axes[2].max_value; m_xtablet.PressureLevels = xvi->axes[2].max_value;
if (xvi->num_axes > 3) {
/* this is assuming that the tablet has the same tilt resolution in both /* this is assuming that the tablet has the same tilt resolution in both
* positive and negative directions. It would be rather weird if it didn't.. */ * positive and negative directions. It would be rather weird if it didn't.. */
m_xtablet.XtiltLevels = xvi->axes[3].max_value; m_xtablet.XtiltLevels = xvi->axes[3].max_value;
m_xtablet.YtiltLevels = xvi->axes[4].max_value; m_xtablet.YtiltLevels = xvi->axes[4].max_value;
}
else {
m_xtablet.XtiltLevels = 0;
m_xtablet.YtiltLevels = 0;
}
break; break;
} }
@ -1967,7 +1981,9 @@ void GHOST_SystemX11::initXInputDevices()
m_xtablet.StylusID = 0; m_xtablet.StylusID = 0;
} }
} }
else if (m_xtablet.EraserDevice == NULL && is_eraser(device_info[i].name, device_type)) { else if ((m_xtablet.EraserDevice == NULL) &&
(is_eraser(device_info[i].name, device_type)))
{
// printf("\tfound eraser\n"); // printf("\tfound eraser\n");
m_xtablet.EraserID = device_info[i].id; m_xtablet.EraserID = device_info[i].id;
m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID); m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);

@ -274,34 +274,6 @@ public:
return 0; return 0;
} }
/**
* Atom used for ICCCM, WM-spec and Motif.
* We only need get this atom at the start, it's relative
* to the display not the window and are public for every
* window that need it.
*/
Atom m_wm_state;
Atom m_wm_change_state;
Atom m_net_state;
Atom m_net_max_horz;
Atom m_net_max_vert;
Atom m_net_fullscreen;
Atom m_motif;
Atom m_wm_take_focus;
Atom m_wm_protocols;
Atom m_delete_window_atom;
/* Atoms for Selection, copy & paste. */
Atom m_targets;
Atom m_string;
Atom m_compound_text;
Atom m_text;
Atom m_clipboard;
Atom m_primary;
Atom m_xclip_out;
Atom m_incr;
Atom m_utf8_string;
#ifdef WITH_X11_XINPUT #ifdef WITH_X11_XINPUT
typedef struct GHOST_TabletX11 { typedef struct GHOST_TabletX11 {
XDevice *StylusDevice; XDevice *StylusDevice;
@ -323,6 +295,39 @@ public:
} }
#endif // WITH_X11_XINPUT #endif // WITH_X11_XINPUT
struct {
/**
* Atom used for ICCCM, WM-spec and Motif.
* We only need get this atom at the start, it's relative
* to the display not the window and are public for every
* window that need it.
*/
Atom WM_STATE;
Atom WM_CHANGE_STATE;
Atom _NET_WM_STATE;
Atom _NET_WM_STATE_MAXIMIZED_HORZ;
Atom _NET_WM_STATE_MAXIMIZED_VERT;
Atom _NET_WM_STATE_FULLSCREEN;
Atom _MOTIF_WM_HINTS;
Atom WM_TAKE_FOCUS;
Atom WM_PROTOCOLS;
Atom WM_DELETE_WINDOW;
/* Atoms for Selection, copy & paste. */
Atom TARGETS;
Atom STRING;
Atom COMPOUND_TEXT;
Atom TEXT;
Atom CLIPBOARD;
Atom PRIMARY;
Atom XCLIP_OUT;
Atom INCR;
Atom UTF8_STRING;
#ifdef WITH_X11_XINPUT
Atom TABLET;
#endif
} m_atom;
private: private:
Display *m_display; Display *m_display;

@ -395,16 +395,16 @@ GHOST_WindowX11(
XFree(xclasshint); XFree(xclasshint);
/* The basic for a good ICCCM "work" */ /* The basic for a good ICCCM "work" */
if (m_system->m_wm_protocols) { if (m_system->m_atom.WM_PROTOCOLS) {
natom = 0; natom = 0;
if (m_system->m_delete_window_atom) { if (m_system->m_atom.WM_DELETE_WINDOW) {
atoms[natom] = m_system->m_delete_window_atom; atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW;
natom++; natom++;
} }
if (m_system->m_wm_take_focus) { if (m_system->m_atom.WM_TAKE_FOCUS) {
atoms[natom] = m_system->m_wm_take_focus; atoms[natom] = m_system->m_atom.WM_TAKE_FOCUS;
natom++; natom++;
} }
@ -744,7 +744,7 @@ void GHOST_WindowX11::icccmSetState(int state)
xev.xclient.display = m_display; xev.xclient.display = m_display;
xev.xclient.window = m_window; xev.xclient.window = m_window;
xev.xclient.format = 32; xev.xclient.format = 32;
xev.xclient.message_type = m_system->m_wm_change_state; xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE;
xev.xclient.data.l[0] = state; xev.xclient.data.l[0] = state;
XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)), XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
False, SubstructureNotifyMask | SubstructureRedirectMask, &xev); False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
@ -758,8 +758,8 @@ int GHOST_WindowX11::icccmGetState(void) const
int format_ret, st; int format_ret, st;
prop_ret = NULL; prop_ret = NULL;
st = XGetWindowProperty(m_display, m_window, m_system->m_wm_state, 0, st = XGetWindowProperty(m_display, m_window, m_system->m_atom.WM_STATE, 0,
0x7fffffff, False, m_system->m_wm_state, &type_ret, 0x7fffffff, False, m_system->m_atom.WM_STATE, &type_ret,
&format_ret, &num_ret, &bytes_after, &prop_ret); &format_ret, &num_ret, &bytes_after, &prop_ret);
if ((st == Success) && (prop_ret) && (num_ret == 2)) if ((st == Success) && (prop_ret) && (num_ret == 2))
@ -780,7 +780,7 @@ void GHOST_WindowX11::netwmMaximized(bool set)
xev.xclient.serial = 0; xev.xclient.serial = 0;
xev.xclient.send_event = True; xev.xclient.send_event = True;
xev.xclient.window = m_window; xev.xclient.window = m_window;
xev.xclient.message_type = m_system->m_net_state; xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
xev.xclient.format = 32; xev.xclient.format = 32;
if (set == True) if (set == True)
@ -788,8 +788,8 @@ void GHOST_WindowX11::netwmMaximized(bool set)
else else
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
xev.xclient.data.l[1] = m_system->m_net_max_horz; xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ;
xev.xclient.data.l[2] = m_system->m_net_max_vert; xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
xev.xclient.data.l[3] = 0; xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0; xev.xclient.data.l[4] = 0;
XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)), XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
@ -806,15 +806,15 @@ bool GHOST_WindowX11::netwmIsMaximized(void) const
prop_ret = NULL; prop_ret = NULL;
st = False; st = False;
ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0, ret = XGetWindowProperty(m_display, m_window, m_system->m_atom._NET_WM_STATE, 0,
0x7fffffff, False, XA_ATOM, &type_ret, &format_ret, 0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
&num_ret, &bytes_after, &prop_ret); &num_ret, &bytes_after, &prop_ret);
if ((ret == Success) && (prop_ret) && (format_ret == 32)) { if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
count = 0; count = 0;
for (i = 0; i < num_ret; i++) { for (i = 0; i < num_ret; i++) {
if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_horz) if (((unsigned long *) prop_ret)[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_HORZ)
count++; count++;
if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_vert) if (((unsigned long *) prop_ret)[i] == m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT)
count++; count++;
if (count == 2) { if (count == 2) {
st = True; st = True;
@ -836,7 +836,7 @@ void GHOST_WindowX11::netwmFullScreen(bool set)
xev.xclient.serial = 0; xev.xclient.serial = 0;
xev.xclient.send_event = True; xev.xclient.send_event = True;
xev.xclient.window = m_window; xev.xclient.window = m_window;
xev.xclient.message_type = m_system->m_net_state; xev.xclient.message_type = m_system->m_atom._NET_WM_STATE;
xev.xclient.format = 32; xev.xclient.format = 32;
if (set == True) if (set == True)
@ -844,7 +844,7 @@ void GHOST_WindowX11::netwmFullScreen(bool set)
else else
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
xev.xclient.data.l[1] = m_system->m_net_fullscreen; xev.xclient.data.l[1] = m_system->m_atom._NET_WM_STATE_FULLSCREEN;
xev.xclient.data.l[2] = 0; xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0; xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0; xev.xclient.data.l[4] = 0;
@ -862,12 +862,12 @@ bool GHOST_WindowX11::netwmIsFullScreen(void) const
prop_ret = NULL; prop_ret = NULL;
st = False; st = False;
ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0, ret = XGetWindowProperty(m_display, m_window, m_system->m_atom._NET_WM_STATE, 0,
0x7fffffff, False, XA_ATOM, &type_ret, &format_ret, 0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
&num_ret, &bytes_after, &prop_ret); &num_ret, &bytes_after, &prop_ret);
if ((ret == Success) && (prop_ret) && (format_ret == 32)) { if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
for (i = 0; i < num_ret; i++) { for (i = 0; i < num_ret; i++) {
if (((unsigned long *) prop_ret)[i] == m_system->m_net_fullscreen) { if (((unsigned long *) prop_ret)[i] == m_system->m_atom._NET_WM_STATE_FULLSCREEN) {
st = True; st = True;
break; break;
} }
@ -889,8 +889,8 @@ void GHOST_WindowX11::motifFullScreen(bool set)
else else
hints.decorations = 1; hints.decorations = 1;
XChangeProperty(m_display, m_window, m_system->m_motif, XChangeProperty(m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS,
m_system->m_motif, 32, PropModeReplace, m_system->m_atom._MOTIF_WM_HINTS, 32, PropModeReplace,
(unsigned char *) &hints, 4); (unsigned char *) &hints, 4);
} }
@ -905,8 +905,8 @@ bool GHOST_WindowX11::motifIsFullScreen(void) const
prop_ret = NULL; prop_ret = NULL;
state = False; state = False;
st = XGetWindowProperty(m_display, m_window, m_system->m_motif, 0, st = XGetWindowProperty(m_display, m_window, m_system->m_atom._MOTIF_WM_HINTS, 0,
0x7fffffff, False, m_system->m_motif, 0x7fffffff, False, m_system->m_atom._MOTIF_WM_HINTS,
&type_ret, &format_ret, &num_ret, &type_ret, &format_ret, &num_ret,
&bytes_after, &prop_ret); &bytes_after, &prop_ret);
if ((st == Success) && (prop_ret)) { if ((st == Success) && (prop_ret)) {

@ -94,9 +94,9 @@ static void generatTile_FFT(float* const noiseTileData, std::string filename)
for (int x = 0; x < xRes; x++) for (int x = 0; x < xRes; x++)
{ {
int index = x + y * xRes + z * xRes * yRes; int index = x + y * xRes + z * xRes * yRes;
float diff[] = {abs(x - xRes/2), float diff[] = {(float)abs(x - xRes / 2),
abs(y - yRes/2), (float)abs(y - yRes / 2),
abs(z - zRes/2)}; (float)abs(z - zRes / 2)};
float radius = sqrtf(diff[0] * diff[0] + float radius = sqrtf(diff[0] * diff[0] +
diff[1] * diff[1] + diff[1] * diff[1] +
diff[2] * diff[2]) / (xRes / 2); diff[2] * diff[2]) / (xRes / 2);

@ -1654,7 +1654,7 @@ void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame
fuel[index] -= burning_rate * dt; fuel[index] -= burning_rate * dt;
if (fuel[index] < 0.0f) fuel[index] = 0.0f; if (fuel[index] < 0.0f) fuel[index] = 0.0f;
/* process reaction coordinate */ /* process reaction coordinate */
if (orig_fuel) { if (orig_fuel > FLT_EPSILON) {
react[index] *= fuel[index]/orig_fuel; react[index] *= fuel[index]/orig_fuel;
react_coord = react[index]; react_coord = react[index];
} }
@ -1681,7 +1681,7 @@ void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame
heat[index] = (1.0f-flame[index])*ignition_point + flame[index]*temp_max; heat[index] = (1.0f-flame[index])*ignition_point + flame[index]*temp_max;
/* mix new color */ /* mix new color */
if (r && smoke_emit) { if (r && smoke_emit > FLT_EPSILON) {
float smoke_factor = smoke[index]/(orig_smoke+smoke_emit); float smoke_factor = smoke[index]/(orig_smoke+smoke_emit);
r[index] = (r[index] + _flame_smoke_color[0] * smoke_emit) * smoke_factor; r[index] = (r[index] + _flame_smoke_color[0] * smoke_emit) * smoke_factor;
g[index] = (g[index] + _flame_smoke_color[1] * smoke_emit) * smoke_factor; g[index] = (g[index] + _flame_smoke_color[1] * smoke_emit) * smoke_factor;

@ -387,7 +387,7 @@ def dump_py_messages_from_files(messages, check_ctxt, files):
estr_ls.append(estr) estr_ls.append(estr)
nds_ls.extend(nds) nds_ls.extend(nds)
ret = _extract_string_merge(estr_ls, nds_ls) ret = _extract_string_merge(estr_ls, nds_ls)
print(ret) #print(ret)
return ret return ret
def extract_strings_split(node): def extract_strings_split(node):

@ -83,6 +83,7 @@ LANGUAGES = (
(37, "Amharic (አማርኛ)", "am_ET"), (37, "Amharic (አማርኛ)", "am_ET"),
(38, "Uzbek (Oʻzbek)", "uz_UZ"), (38, "Uzbek (Oʻzbek)", "uz_UZ"),
(39, "Uzbek Cyrillic (Ўзбек)", "uz_UZ@cyrillic"), (39, "Uzbek Cyrillic (Ўзбек)", "uz_UZ@cyrillic"),
(40, "Hindi (मानक हिन्दी)", "hi_IN"),
) )
# Name of language file used by Blender to generate translations' menu. # Name of language file used by Blender to generate translations' menu.
@ -93,7 +94,7 @@ LANGUAGES_FILE = "languages"
IMPORT_MIN_LEVEL = -1 IMPORT_MIN_LEVEL = -1
# Languages in /branches we do not want to import in /trunk currently... # Languages in /branches we do not want to import in /trunk currently...
IMPORT_LANGUAGES_SKIP = {'am', 'bg', 'fi', 'el', 'et', 'ko', 'ne', 'pl', 'ro', 'uz', 'uz@cyrillic'} IMPORT_LANGUAGES_SKIP = {'am', 'bg', 'fi', 'el', 'et', 'hi', 'ne', 'pl', 'ro', 'uz', 'uz@cyrillic'}
# The comment prefix used in generated messages.txt file. # The comment prefix used in generated messages.txt file.
MSG_COMMENT_PREFIX = "#~ " MSG_COMMENT_PREFIX = "#~ "
@ -367,7 +368,10 @@ FILE_NAME_POT = os.path.join(TRUNK_PO_DIR, ".".join((DOMAIN, "pot")))
# Other py files that should be searched for ui strings, relative to SOURCE_DIR. # Other py files that should be searched for ui strings, relative to SOURCE_DIR.
# Needed for Cycles, currently... # Needed for Cycles, currently...
CUSTOM_PY_UI_FILES = [os.path.join("intern", "cycles", "blender", "addon", "ui.py"),] CUSTOM_PY_UI_FILES = [
os.path.join("intern", "cycles", "blender", "addon", "ui.py"),
os.path.join("release", "scripts", "modules", "rna_prop_ui.py"),
]
# A cache storing validated msgids, to avoid re-spellchecking them. # A cache storing validated msgids, to avoid re-spellchecking them.

@ -225,6 +225,7 @@ dict_uimsgs = {
"loc", "rot", "pos", "loc", "rot", "pos",
"lorem", "lorem",
"luma", "luma",
"mem",
"multicam", "multicam",
"num", "num",
"ok", "ok",

@ -97,10 +97,13 @@ def main():
if os.path.exists(po): if os.path.exists(po):
pool_data.append((po, lang, pot_msgs)) pool_data.append((po, lang, pot_msgs))
with concurrent.futures.ProcessPoolExecutor() as executor: for r in map(process_po, pool_data):
for r in executor.map(process_po, pool_data, timeout=600):
if r != 0: if r != 0:
ret = r ret = r
#with concurrent.futures.ProcessPoolExecutor() as executor:
#for r in executor.map(process_po, pool_data, timeout=600):
#if r != 0:
#ret = r
return ret return ret

@ -21,6 +21,7 @@
# Some misc utilities... # Some misc utilities...
import collections import collections
import concurrent.futures
import copy import copy
import os import os
import re import re
@ -61,6 +62,35 @@ def is_valid_po_path(path):
return bool(_valid_po_path_re.match(path)) return bool(_valid_po_path_re.match(path))
def get_best_similar(data):
import difflib
key, use_similar, similar_pool = data
# try to find some close key in existing messages...
# Optimized code inspired by difflib.get_close_matches (as we only need the best match).
# We also consider to never make a match when len differs more than -len_key / 2, +len_key * 2 (which is valid
# as long as use_similar is not below ~0.7).
# Gives an overall ~20% of improvement!
#tmp = difflib.get_close_matches(key[1], similar_pool, n=1, cutoff=use_similar)
#if tmp:
#tmp = tmp[0]
tmp = None
s = difflib.SequenceMatcher()
s.set_seq2(key[1])
len_key = len(key[1])
min_len = len_key // 2
max_len = len_key * 2
for x in similar_pool:
if min_len < len(x) < max_len:
s.set_seq1(x)
if s.real_quick_ratio() >= use_similar and s.quick_ratio() >= use_similar:
sratio = s.ratio()
if sratio >= use_similar:
tmp = x
use_similar = sratio
return key, tmp
class I18nMessage: class I18nMessage:
""" """
Internal representation of a message. Internal representation of a message.
@ -233,40 +263,71 @@ class I18nMessages:
existing one. Messages no more found in ref will be marked as commented if keep_old_commented is True, existing one. Messages no more found in ref will be marked as commented if keep_old_commented is True,
or removed. or removed.
""" """
import difflib
similar_pool = {} similar_pool = {}
if use_similar > 0.0: if use_similar > 0.0:
for key, msg in self.msgs.items(): for key, msg in self.msgs.items():
if msg.msgstr: # No need to waste time with void translations! if msg.msgstr: # No need to waste time with void translations!
similar_pool.setdefault(key[1], set()).add(key) similar_pool.setdefault(key[1], set()).add(key)
msgs = self._new_messages() msgs = self._new_messages().fromkeys(ref.msgs.keys())
for (key, msg) in ref.msgs.items(): ref_keys = set(ref.msgs.keys())
if key in self.msgs: org_keys = set(self.msgs.keys())
msgs[key] = self.msgs[key] new_keys = ref_keys - org_keys
msgs[key].sources = msg.sources removed_keys = org_keys - ref_keys
else:
skey = None # First process keys present in both org and ref messages.
if use_similar > 0.0: for key in ref_keys - new_keys:
# try to find some close key in existing messages... msg, refmsg = self.msgs[key], ref.msgs[key]
tmp = difflib.get_close_matches(key[1], similar_pool, n=1, cutoff=use_similar) msg.sources = refmsg.sources
if tmp: msg.is_commented = refmsg.is_commented
tmp = tmp[0] msg.is_fuzzy = refmsg.is_fuzzy
# Try to get the same context, else just get one...
skey = (key[0], tmp)
if skey not in similar_pool[tmp]:
skey = tuple(similar_pool[tmp])[0]
msgs[key] = msg msgs[key] = msg
if skey:
msgs[key].msgstr = self.msgs[skey].msgstr # Next process new keys.
msgs[key].is_fuzzy = True if use_similar > 0.0:
with concurrent.futures.ProcessPoolExecutor() as exctr:
for key, msgid in exctr.map(get_best_similar,
tuple((nk, use_similar, tuple(similar_pool.keys())) for nk in new_keys)):
if msgid:
# Try to get the same context, else just get one...
skey = (key[0], msgid)
if skey not in similar_pool[msgid]:
skey = tuple(similar_pool[msgid])[0]
# We keep org translation and comments, and mark message as fuzzy.
msg, refmsg = copy.deepcopy(self.msgs[skey]), ref.msgs[key]
msg.msgctxt = refmsg.msgctxt
msg.msgid = refmsg.msgid
msg.sources = refmsg.sources
msg.is_fuzzy = True
msg.is_commented = refmsg.is_commented
msgs[key] = msg
else:
msgs[key] = ref.msgs[key]
else:
for key in new_keys:
msgs[key] = ref.msgs[key]
# Add back all "old" and already commented messages as commented ones, if required # Add back all "old" and already commented messages as commented ones, if required
# (and translation was not void!). # (and translation was not void!).
if keep_old_commented: if keep_old_commented:
for key, msg in self.msgs.items(): for key in removed_keys:
if key not in msgs and msg.msgstr: msgs[key] = self.msgs[key]
msgs[key] = msg
msgs[key].is_commented = True msgs[key].is_commented = True
msgs[key].sources = []
# Special 'meta' message, change project ID version and pot creation date...
key = ("", "")
rep = []
markers = ("Project-Id-Version:", "POT-Creation-Date:")
for mrk in markers:
for rl in ref.msgs[key].msgstr_lines:
if rl.startswith(mrk):
for idx, ml in enumerate(msgs[key].msgstr_lines):
if ml.startswith(mrk):
rep.append((idx, rl))
for idx, txt in rep:
msgs[key].msgstr_lines[idx] = txt
# And finalize the update! # And finalize the update!
self.msgs = msgs self.msgs = msgs

@ -58,6 +58,7 @@ def main():
# from bpy.types import Panel # from bpy.types import Panel
sys.modules["bpy.app"] = app sys.modules["bpy.app"] = app
sys.modules["bpy.app.handlers"] = app.handlers sys.modules["bpy.app.handlers"] = app.handlers
sys.modules["bpy.app.translations"] = app.translations
sys.modules["bpy.types"] = types sys.modules["bpy.types"] = types
#~ if "-d" in sys.argv: # Enable this to measure start up speed #~ if "-d" in sys.argv: # Enable this to measure start up speed

@ -148,7 +148,7 @@ def draw(layout, context, context_member, property_type, use_edit=True):
if use_edit: if use_edit:
row = split.row(align=True) row = split.row(align=True)
props = row.operator("wm.properties_edit", text="edit") props = row.operator("wm.properties_edit", text="Edit")
assign_props(props, val_draw, key) assign_props(props, val_draw, key)
props = row.operator("wm.properties_remove", text="", icon='ZOOMOUT') props = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')

@ -296,8 +296,8 @@
</panelcolors> </panelcolors>
<gradients> <gradients>
<ThemeGradientColors show_grad="FALSE" <ThemeGradientColors show_grad="FALSE"
gradient="#000000" gradient="#393939"
high_gradient="#393939"> high_gradient="#000000">
</ThemeGradientColors> </ThemeGradientColors>
</gradients> </gradients>
</ThemeSpaceGradient> </ThemeSpaceGradient>

@ -297,7 +297,7 @@
<gradients> <gradients>
<ThemeGradientColors show_grad="FALSE" <ThemeGradientColors show_grad="FALSE"
gradient="#000000" gradient="#000000"
high_gradient="#393939"> high_gradient="#757575">
</ThemeGradientColors> </ThemeGradientColors>
</gradients> </gradients>
</ThemeSpaceGradient> </ThemeSpaceGradient>

@ -297,7 +297,7 @@
<gradients> <gradients>
<ThemeGradientColors show_grad="FALSE" <ThemeGradientColors show_grad="FALSE"
gradient="#000000" gradient="#000000"
high_gradient="#393939"> high_gradient="#4b4b4b">
</ThemeGradientColors> </ThemeGradientColors>
</gradients> </gradients>
</ThemeSpaceGradient> </ThemeSpaceGradient>

@ -297,7 +297,7 @@
<gradients> <gradients>
<ThemeGradientColors show_grad="FALSE" <ThemeGradientColors show_grad="FALSE"
gradient="#000000" gradient="#000000"
high_gradient="#393939"> high_gradient="#7f818d">
</ThemeGradientColors> </ThemeGradientColors>
</gradients> </gradients>
</ThemeSpaceGradient> </ThemeSpaceGradient>

@ -297,7 +297,7 @@
<gradients> <gradients>
<ThemeGradientColors show_grad="FALSE" <ThemeGradientColors show_grad="FALSE"
gradient="#000000" gradient="#000000"
high_gradient="#393939"> high_gradient="#131311">
</ThemeGradientColors> </ThemeGradientColors>
</gradients> </gradients>
</ThemeSpaceGradient> </ThemeSpaceGradient>

@ -133,46 +133,54 @@ kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True)
kmi.properties.data_path = 'space_data.viewport_shade' kmi.properties.data_path = 'space_data.viewport_shade'
kmi.properties.value_1 = 'TEXTURED' kmi.properties.value_1 = 'TEXTURED'
kmi.properties.value_2 = 'SOLID' kmi.properties.value_2 = 'SOLID'
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK') kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE')
kmi.properties.extend = False kmi.properties.extend = False
kmi.properties.center = False kmi.properties.center = False
kmi.properties.object = False kmi.properties.object = False
kmi.properties.enumerate = False kmi.properties.enumerate = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', shift=True) kmi.properties.toggle = False
kmi.properties.extend = True kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True)
kmi.properties.extend = False
kmi.properties.center = False kmi.properties.center = False
kmi.properties.object = False kmi.properties.object = False
kmi.properties.enumerate = False kmi.properties.enumerate = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', ctrl=True) kmi.properties.toggle = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True)
kmi.properties.extend = False kmi.properties.extend = False
kmi.properties.center = True kmi.properties.center = True
kmi.properties.object = False kmi.properties.object = False
kmi.properties.enumerate = False kmi.properties.enumerate = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', alt=True) kmi.properties.toggle = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', alt=True)
kmi.properties.extend = False kmi.properties.extend = False
kmi.properties.center = False kmi.properties.center = False
kmi.properties.object = False kmi.properties.object = False
kmi.properties.enumerate = True kmi.properties.enumerate = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', shift=True, ctrl=True) kmi.properties.toggle = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True)
kmi.properties.extend = True kmi.properties.extend = True
kmi.properties.center = True kmi.properties.center = True
kmi.properties.object = False kmi.properties.object = False
kmi.properties.enumerate = False kmi.properties.enumerate = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', ctrl=True, alt=True) kmi.properties.toggle = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True, alt=True)
kmi.properties.extend = False kmi.properties.extend = False
kmi.properties.center = True kmi.properties.center = True
kmi.properties.object = False kmi.properties.object = False
kmi.properties.enumerate = True kmi.properties.enumerate = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', shift=True, alt=True) kmi.properties.toggle = False
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, alt=True)
kmi.properties.extend = True kmi.properties.extend = True
kmi.properties.center = False kmi.properties.center = False
kmi.properties.object = False kmi.properties.object = False
kmi.properties.enumerate = True kmi.properties.enumerate = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'CLICK', shift=True, ctrl=True, alt=True) kmi.properties.toggle = True
kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True, alt=True)
kmi.properties.extend = True kmi.properties.extend = True
kmi.properties.center = True kmi.properties.center = True
kmi.properties.object = False kmi.properties.object = False
kmi.properties.enumerate = True kmi.properties.enumerate = True
kmi.properties.toggle = True
kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_S', 'ANY') kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_S', 'ANY')
kmi.properties.extend = False kmi.properties.extend = False
kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True) kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
@ -218,7 +226,7 @@ kmi.properties.use = True
kmi = km.keymap_items.new('transform.mirror', 'M', 'PRESS', ctrl=True) kmi = km.keymap_items.new('transform.mirror', 'M', 'PRESS', ctrl=True)
kmi = km.keymap_items.new('wm.context_toggle', 'TAB', 'PRESS', shift=True) kmi = km.keymap_items.new('wm.context_toggle', 'TAB', 'PRESS', shift=True)
kmi.properties.data_path = 'tool_settings.use_snap' kmi.properties.data_path = 'tool_settings.use_snap'
kmi = km.keymap_items.new('WM_OT_context_menu_enum', 'TAB', 'PRESS', shift=True, ctrl=True); kmi = km.keymap_items.new('WM_OT_context_menu_enum', 'TAB', 'PRESS', shift=True, ctrl=True)
kmi.properties.data_path = 'tool_settings.snap_element' kmi.properties.data_path = 'tool_settings.snap_element'
kmi = km.keymap_items.new('view3d.enable_manipulator', 'W', 'PRESS') kmi = km.keymap_items.new('view3d.enable_manipulator', 'W', 'PRESS')
@ -310,10 +318,8 @@ kmi = km.keymap_items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
kmi.properties.level = 4 kmi.properties.level = 4
kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True) kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
kmi.properties.level = 5 kmi.properties.level = 5
# TODO: only used to de-seletc everything when click outside of object, kmi = km.keymap_items.new('object.select_all', 'SELECTMOUSE', 'CLICK')
# and that's not best way to do this and this way is completely unpredictable kmi.properties.action = 'DESELECT'
#kmi = km.keymap_items.new('object.select_all', 'SELECTMOUSE', 'CLICK')
#kmi.properties.action = 'DESELECT'
# Map Mesh # Map Mesh
km = kc.keymaps.new('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False) km = kc.keymaps.new('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
@ -399,10 +405,8 @@ kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
kmi.properties.data_path = 'tool_settings.proportional_edit' kmi.properties.data_path = 'tool_settings.proportional_edit'
kmi.properties.value_1 = 'DISABLED' kmi.properties.value_1 = 'DISABLED'
kmi.properties.value_2 = 'CONNECTED' kmi.properties.value_2 = 'CONNECTED'
# TODO: only used to de-seletc everything when click outside of object, kmi = km.keymap_items.new('mesh.select_all', 'SELECTMOUSE', 'CLICK')
# and that's not best way to do this and this way is completely unpredictable kmi.properties.action = 'DESELECT'
#kmi = km.keymap_items.new('mesh.select_all', 'SELECTMOUSE', 'CLICK')
#kmi.properties.action = 'DESELECT'
kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True) kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
kmi.properties.level = 0 kmi.properties.level = 0
kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True) kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)

@ -190,7 +190,8 @@ class BakeToKeyframes(Operator):
class ConnectRigidBodies(Operator): class ConnectRigidBodies(Operator):
'''Create rigid body constraints between selected and active rigid bodies''' """Create rigid body constraints between """ \
"""selected and active rigid bodies"""
bl_idname = "rigidbody.connect" bl_idname = "rigidbody.connect"
bl_label = "Connect Rigid Bodies" bl_label = "Connect Rigid Bodies"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
@ -232,7 +233,11 @@ class ConnectRigidBodies(Operator):
loc = obj.location loc = obj.location
else: else:
loc = (obj_act.location + obj.location) / 2.0 loc = (obj_act.location + obj.location) / 2.0
bpy.ops.object.add(type='EMPTY', view_align=False, enter_editmode=False, location=loc) # TODO: use bpy.data.objects.new(...)
bpy.ops.object.add(type='EMPTY',
view_align=False,
enter_editmode=False,
location=loc)
bpy.ops.rigidbody.constraint_add() bpy.ops.rigidbody.constraint_add()
con_obj = context.active_object con_obj = context.active_object
con_obj.empty_draw_type = 'ARROWS' con_obj.empty_draw_type = 'ARROWS'
@ -246,7 +251,7 @@ class ConnectRigidBodies(Operator):
# restore selection # restore selection
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
for obj in objects: for obj in objects:
obj.select = True; obj.select = True
scene.objects.active = obj_act scene.objects.active = obj_act
return {'FINISHED'} return {'FINISHED'}
else: else:

@ -124,7 +124,7 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
rows = 2 rows = 2
if group: if group:
rows = 5 rows = 5
row.template_list("UI_UL_list", "", pose, "bone_groups", pose.bone_groups, "active_index", rows=rows) row.template_list("UI_UL_list", "bone_groups", pose, "bone_groups", pose.bone_groups, "active_index", rows=rows)
col = row.column(align=True) col = row.column(align=True)
col.active = (ob.proxy is None) col.active = (ob.proxy is None)

@ -19,6 +19,7 @@
# <pep8 compliant> # <pep8 compliant>
import bpy import bpy
from bpy.types import Panel from bpy.types import Panel
from bpy.app.translations import pgettext_iface as iface_
class ModifierButtonsPanel(): class ModifierButtonsPanel():
@ -265,8 +266,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.prop(md, "angle_limit") layout.prop(md, "angle_limit")
layout.prop(md, "use_dissolve_boundaries") layout.prop(md, "use_dissolve_boundaries")
pgettext = bpy.app.translations.pgettext layout.label(text=iface_("Face Count: %d") % md.face_count, translate=False)
layout.label(text=pgettext("Face Count: %d") % md.face_count, translate=False)
def DISPLACE(self, layout, ob, md): def DISPLACE(self, layout, ob, md):
has_texture = (md.texture is not None) has_texture = (md.texture is not None)

@ -20,6 +20,7 @@
import bpy import bpy
from bpy.types import Menu, Panel, UIList from bpy.types import Menu, Panel, UIList
from rna_prop_ui import PropertyPanel from rna_prop_ui import PropertyPanel
from bpy.app.translations import pgettext_iface as iface_
def active_node_mat(mat): def active_node_mat(mat):
@ -80,8 +81,7 @@ class MATERIAL_UL_matslots(UIList):
if ma and not context.scene.render.use_shading_nodes: if ma and not context.scene.render.use_shading_nodes:
manode = ma.active_node_material manode = ma.active_node_material
if manode: if manode:
pgettext = bpy.app.translations.pgettext layout.label(text=iface_("Node %s") % manode.name, translate=False, icon_value=layout.icon(manode))
layout.label(text=pgettext("Node %s") % manode.name, translate=False, icon_value=layout.icon(manode))
elif ma.use_nodes: elif ma.use_nodes:
layout.label(text="Node <none>") layout.label(text="Node <none>")
else: else:

@ -20,6 +20,7 @@
import bpy import bpy
from bpy.types import Panel from bpy.types import Panel
from rna_prop_ui import PropertyPanel from rna_prop_ui import PropertyPanel
from bpy.app.translations import pgettext_iface as iface_
from bl_ui.properties_physics_common import (point_cache_ui, from bl_ui.properties_physics_common import (point_cache_ui,
effector_weights_ui, effector_weights_ui,
@ -148,8 +149,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
#row.label(text="Render") #row.label(text="Render")
if part.is_fluid: if part.is_fluid:
pgettext = bpy.app.translations.pgettext layout.label(text=iface_("%d fluid particles for this frame") % part.count, translate=False)
layout.label(text=pgettext("%d fluid particles for this frame") % part.count, translate=False)
return return
row = col.row() row = col.row()
@ -543,7 +543,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
# spacing between particles when the fluid is at rest. This # spacing between particles when the fluid is at rest. This
# makes it easier to set stable initial conditions. # makes it easier to set stable initial conditions.
particle_volume = part.mass / fluid.rest_density particle_volume = part.mass / fluid.rest_density
spacing = pow(particle_volume, 1/3) spacing = pow(particle_volume, 1.0 / 3.0)
sub = col.row() sub = col.row()
sub.label(text="Spacing: %g" % spacing) sub.label(text="Spacing: %g" % spacing)

@ -21,6 +21,8 @@
import bpy import bpy
from bpy.types import Panel from bpy.types import Panel
i18n_default_ctxt = bpy.app.translations.contexts.default
class PhysicButtonsPanel(): class PhysicButtonsPanel():
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
@ -37,19 +39,21 @@ def physics_add(self, layout, md, name, type, typeicon, toggles):
sub = layout.row(align=True) sub = layout.row(align=True)
if md: if md:
sub.context_pointer_set("modifier", md) sub.context_pointer_set("modifier", md)
sub.operator("object.modifier_remove", text=name, icon='X') sub.operator("object.modifier_remove", text=name, text_ctxt=i18n_default_ctxt, icon='X')
if(toggles): if(toggles):
sub.prop(md, "show_render", text="") sub.prop(md, "show_render", text="")
sub.prop(md, "show_viewport", text="") sub.prop(md, "show_viewport", text="")
else: else:
sub.operator("object.modifier_add", text=name, icon=typeicon).type = type sub.operator("object.modifier_add", text=name, text_ctxt=i18n_default_ctxt, icon=typeicon).type = type
def physics_add_special(self, layout, data, name, addop, removeop, typeicon): def physics_add_special(self, layout, data, name, addop, removeop, typeicon):
sub = layout.row(align=True) sub = layout.row(align=True)
if data: if data:
sub.operator(removeop, text=name, icon='X') sub.operator(removeop, text=name, text_ctxt=i18n_default_ctxt, icon='X')
else: else:
sub.operator(addop, text=name, icon=typeicon) sub.operator(addop, text=name, text_ctxt=i18n_default_ctxt, icon=typeicon)
class PHYSICS_PT_add(PhysicButtonsPanel, Panel): class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
bl_label = "" bl_label = ""

@ -19,6 +19,7 @@
# <pep8 compliant> # <pep8 compliant>
import bpy import bpy
from bpy.types import Panel, Menu from bpy.types import Panel, Menu
from bpy.app.translations import pgettext_iface as iface_
class FLUID_MT_presets(Menu): class FLUID_MT_presets(Menu):
@ -64,8 +65,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
if fluid.type == 'DOMAIN': if fluid.type == 'DOMAIN':
# odd formatting here so translation script can extract string # odd formatting here so translation script can extract string
pgettext = bpy.app.translations.pgettext layout.operator("fluid.bake", text=iface_("Bake (Req. Memory: %s)") % fluid.memory_estimate,
layout.operator("fluid.bake", text=pgettext("Bake (Req. Memory: %s)") % fluid.memory_estimate,
translate=False, icon='MOD_FLUIDSIM') translate=False, icon='MOD_FLUIDSIM')
split = layout.split() split = layout.split()

@ -32,15 +32,15 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
ob = context.object obj = context.object
rd = context.scene.render return (obj and obj.rigid_body and
return (ob and ob.rigid_body and (not rd.use_game_engine)) (not context.scene.render.use_game_engine))
def draw_header(self, context): def draw_header(self, context):
obj = context.object obj = context.object
rbo = obj.rigid_body rbo = obj.rigid_body
if rbo is not None: if rbo is not None:
self.layout.prop(rbo, "enabled", text=""); self.layout.prop(rbo, "enabled", text="")
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -61,7 +61,8 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return (context.object and context.object.rigid_body and obj = context.object
return (obj and obj.rigid_body and
(not context.scene.render.use_game_engine)) (not context.scene.render.use_game_engine))
def draw(self, context): def draw(self, context):
@ -84,7 +85,7 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
if rbo.collision_shape in {'MESH', 'CONE'}: if rbo.collision_shape in {'MESH', 'CONE'}:
col.prop(rbo, "collision_margin", text="Margin") col.prop(rbo, "collision_margin", text="Margin")
else: else:
col.prop(rbo, "use_margin"); col.prop(rbo, "use_margin")
sub = col.column() sub = col.column()
sub.active = rbo.use_margin sub.active = rbo.use_margin
sub.prop(rbo, "collision_margin", text="Margin") sub.prop(rbo, "collision_margin", text="Margin")
@ -98,8 +99,9 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return (context.object and context.object.rigid_body and obj = context.object
context.object.rigid_body.type == 'ACTIVE' and return (obj and obj.rigid_body and
obj.rigid_body.type == 'ACTIVE' and
(not context.scene.render.use_game_engine)) (not context.scene.render.use_game_engine))
def draw(self, context): def draw(self, context):
@ -112,7 +114,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
#col.label(text="Activation:") #col.label(text="Activation:")
# XXX: settings such as activate on collison/etc. # XXX: settings such as activate on collison/etc.
split = layout.split(); split = layout.split()
col = split.column() col = split.column()
col.label(text="Deactivation:") col.label(text="Deactivation:")

@ -26,6 +26,7 @@ from bl_ui.properties_physics_common import (
effector_weights_ui, effector_weights_ui,
) )
class SCENE_UL_keying_set_paths(UIList): class SCENE_UL_keying_set_paths(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.KeyingSetPath) # assert(isinstance(item, bpy.types.KeyingSetPath)

@ -20,6 +20,7 @@
import bpy import bpy
from bpy.types import Panel, Header, Menu, UIList from bpy.types import Panel, Header, Menu, UIList
from bpy.app.translations import pgettext_iface as iface_
class CLIP_UL_tracking_objects(UIList): class CLIP_UL_tracking_objects(UIList):
@ -28,10 +29,14 @@ class CLIP_UL_tracking_objects(UIList):
# assert(isinstance(item, bpy.types.MovieTrackingObject) # assert(isinstance(item, bpy.types.MovieTrackingObject)
tobj = item tobj = item
if self.layout_type in {'DEFAULT', 'COMPACT'}: if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.label(text=tobj.name, translate=False, icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA') layout.label(text=tobj.name, translate=False,
icon='CAMERA_DATA' if tobj.is_camera
else 'OBJECT_DATA')
elif self.layout_type in {'GRID'}: elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER' layout.alignment = 'CENTER'
layout.label(text="", icon='CAMERA_DATA' if tobj.is_camera else 'OBJECT_DATA') layout.label(text="",
icon='CAMERA_DATA' if tobj.is_camera
else 'OBJECT_DATA')
class CLIP_HT_header(Header): class CLIP_HT_header(Header):
@ -907,7 +912,7 @@ class CLIP_MT_view(Menu):
ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1)) ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
text = bpy.app.translations.pgettext("Zoom %d:%d") text = iface_("Zoom %d:%d")
for a, b in ratios: for a, b in ratios:
layout.operator("clip.view_zoom_ratio", layout.operator("clip.view_zoom_ratio",
text=text % (a, b), text=text % (a, b),

@ -19,8 +19,9 @@
# <pep8 compliant> # <pep8 compliant>
import bpy import bpy
from bpy.types import Header, Menu, Panel from bpy.types import Header, Menu, Panel
from bl_ui.properties_paint_common import UnifiedPaintPanel from bl_ui.properties_paint_common import UnifiedPaintPanel, brush_texture_settings
from bl_ui.properties_paint_common import brush_texture_settings from bpy.app.translations import pgettext_iface as iface_
class ImagePaintPanel(UnifiedPaintPanel): class ImagePaintPanel(UnifiedPaintPanel):
bl_space_type = 'IMAGE_EDITOR' bl_space_type = 'IMAGE_EDITOR'
@ -70,10 +71,8 @@ class IMAGE_MT_view(Menu):
ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1)) ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
pgettext = bpy.app.translations.pgettext
for a, b in ratios: for a, b in ratios:
layout.operator("image.view_zoom_ratio", text=pgettext("Zoom %d:%d") % (a, b), layout.operator("image.view_zoom_ratio", text=iface_("Zoom %d:%d") % (a, b), translate=False).ratio = a / b
translate=False).ratio = a / b
layout.separator() layout.separator()

@ -65,7 +65,7 @@ class INFO_HT_header(Header):
row = layout.row(align=True) row = layout.row(align=True)
row.operator("wm.splash", text="", icon='BLENDER', emboss=False) row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
row.label(text=scene.statistics()) row.label(text=scene.statistics(), translate=False)
# XXX: BEFORE RELEASE, MOVE FILE MENU OUT OF INFO!!! # XXX: BEFORE RELEASE, MOVE FILE MENU OUT OF INFO!!!
""" """

@ -19,6 +19,7 @@
# <pep8 compliant> # <pep8 compliant>
import bpy import bpy
from bpy.types import Header, Menu, Panel from bpy.types import Header, Menu, Panel
from bpy.app.translations import pgettext_iface as iface_
def act_strip(context): def act_strip(context):
@ -420,19 +421,17 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel, Panel):
sub.prop(strip, "frame_start") sub.prop(strip, "frame_start")
sub.prop(strip, "frame_final_duration") sub.prop(strip, "frame_final_duration")
pgettext = bpy.app.translations.pgettext
col = layout.column(align=True) col = layout.column(align=True)
row = col.row() row = col.row()
row.label(text=pgettext("Final Length: %s") % bpy.utils.smpte_from_frame(strip.frame_final_duration), row.label(text=iface_("Final Length: %s") % bpy.utils.smpte_from_frame(strip.frame_final_duration),
translate=False) translate=False)
row = col.row() row = col.row()
row.active = (frame_current >= strip.frame_start and frame_current <= strip.frame_start + strip.frame_duration) row.active = (frame_current >= strip.frame_start and frame_current <= strip.frame_start + strip.frame_duration)
row.label(text=pgettext("Playhead: %d") % (frame_current - strip.frame_start), translate=False) row.label(text=iface_("Playhead: %d") % (frame_current - strip.frame_start), translate=False)
col.label(text=pgettext("Frame Offset %d:%d") % (strip.frame_offset_start, strip.frame_offset_end), col.label(text=iface_("Frame Offset %d:%d") % (strip.frame_offset_start, strip.frame_offset_end),
translate=False)
col.label(text=pgettext("Frame Still %d:%d") % (strip.frame_still_start, strip.frame_still_end),
translate=False) translate=False)
col.label(text=iface_("Frame Still %d:%d") % (strip.frame_still_start, strip.frame_still_end), translate=False)
elem = False elem = False
@ -442,7 +441,7 @@ class SEQUENCER_PT_edit(SequencerButtonsPanel, Panel):
elem = strip.elements[0] elem = strip.elements[0]
if elem and elem.orig_width > 0 and elem.orig_height > 0: if elem and elem.orig_width > 0 and elem.orig_height > 0:
col.label(text=pgettext("Original Dimension: %dx%d") % (elem.orig_width, elem.orig_height), translate=False) col.label(text=iface_("Original Dimension: %dx%d") % (elem.orig_width, elem.orig_height), translate=False)
else: else:
col.label(text="Original Dimension: None") col.label(text="Original Dimension: None")
@ -719,8 +718,7 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
if scene: if scene:
sta = scene.frame_start sta = scene.frame_start
end = scene.frame_end end = scene.frame_end
pgettext = bpy.app.translations.pgettext layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
layout.label(text=pgettext("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel): class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel):
@ -749,8 +747,7 @@ class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel):
if mask: if mask:
sta = mask.frame_start sta = mask.frame_start
end = mask.frame_end end = mask.frame_end
pgettext = bpy.app.translations.pgettext layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
layout.label(text=pgettext("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel): class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):

@ -19,6 +19,7 @@
# <pep8-80 compliant> # <pep8-80 compliant>
import bpy import bpy
from bpy.types import Header, Menu, Panel from bpy.types import Header, Menu, Panel
from bpy.app.translations import pgettext_iface as iface_
class TEXT_HT_header(Header): class TEXT_HT_header(Header):
@ -71,12 +72,11 @@ class TEXT_HT_header(Header):
row = layout.row() row = layout.row()
if text.filepath: if text.filepath:
pgettext = bpy.app.translations.pgettext
if text.is_dirty: if text.is_dirty:
row.label(text=pgettext("File: *%r (unsaved)") % row.label(text=iface_("File: *%r (unsaved)") %
text.filepath, translate=False) text.filepath, translate=False)
else: else:
row.label(text=pgettext("File: %r") % row.label(text=iface_("File: %r") %
text.filepath, translate=False) text.filepath, translate=False)
else: else:
row.label(text="Text: External" row.label(text="Text: External"

@ -19,6 +19,7 @@
# <pep8 compliant> # <pep8 compliant>
import bpy import bpy
from bpy.types import Header, Menu, Panel from bpy.types import Header, Menu, Panel
from bpy.app.translations import pgettext_iface as iface_
def ui_style_items(col, context): def ui_style_items(col, context):
@ -778,10 +779,9 @@ class USERPREF_PT_theme(Panel):
layout.separator() layout.separator()
elif theme.theme_area == 'BONE_COLOR_SETS': elif theme.theme_area == 'BONE_COLOR_SETS':
col = split.column() col = split.column()
pgettext = bpy.app.translations.pgettext
for i, ui in enumerate(theme.bone_color_sets): for i, ui in enumerate(theme.bone_color_sets):
col.label(text=pgettext("Color Set %d:") % (i + 1), translate=False) # i starts from 0 col.label(text=iface_("Color Set %d:") % (i + 1), translate=False) # i starts from 0
row = col.row() row = col.row()

@ -19,6 +19,7 @@
# <pep8 compliant> # <pep8 compliant>
import bpy import bpy
from bpy.types import Menu from bpy.types import Menu
from bpy.app.translations import pgettext_iface as iface_
class USERPREF_MT_keyconfigs(Menu): class USERPREF_MT_keyconfigs(Menu):
@ -97,8 +98,7 @@ class InputKeyMapPanel:
subcol = self.indented_layout(col, level + 1) subcol = self.indented_layout(col, level + 1)
subrow = subcol.row() subrow = subcol.row()
subrow.prop(km, "show_expanded_items", text="", emboss=False) subrow.prop(km, "show_expanded_items", text="", emboss=False)
pgettext = bpy.app.translations.pgettext subrow.label(text=iface_("%s (Global)") % km.name, translate=False)
subrow.label(text=pgettext("%s (Global)") % km.name, translate=False)
else: else:
km.show_expanded_items = True km.show_expanded_items = True

@ -112,9 +112,13 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
/* Default, void context. /* Default, void context.
* WARNING! The "" context is not the same as no (NULL) context at mo/boost::locale level! * WARNING! The "" context is not the same as no (NULL) context at mo/boost::locale level!
* NOTE: We translate BLF_I18NCONTEXT_DEFAULT as BLF_I18NCONTEXT_DEFAULT_BPY in Python, as we cant use "natural"
* None value in rna string properties... :/
* For perf reason, we only use the first char to detect this context, so other contexts should never start
* with the same char!
*/ */
#define BLF_I18NCONTEXT_DEFAULT NULL /* Translated as None in Python. */ #define BLF_I18NCONTEXT_DEFAULT NULL
#define BLF_I18NCONTEXT_DEFAULT_BPY_INTERN "" /* Only used in code, never exposed to user! */ #define BLF_I18NCONTEXT_DEFAULT_BPY "*"
/* Default context for operator names/labels. */ /* Default context for operator names/labels. */
#define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator" #define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator"
@ -168,7 +172,8 @@ typedef struct
#define BLF_I18NCONTEXTS_ITEM(ctxt_id, py_id) {#ctxt_id, py_id, ctxt_id} #define BLF_I18NCONTEXTS_ITEM(ctxt_id, py_id) {#ctxt_id, py_id, ctxt_id}
#define BLF_I18NCONTEXTS_DESC { \ #define BLF_I18NCONTEXTS_DESC { \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT, "default"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT, "default_real"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT_BPY, "default"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "operator_default"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "operator_default"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ACTION, "id_action"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ACTION, "id_action"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ARMATURE, "id_armature"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ARMATURE, "id_armature"), \

@ -94,9 +94,9 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid)
const char *ret; const char *ret;
/*if (msgctxt && !strcmp(msgctxt, BLF_I18NCONTEXT_DEFAULT_BPY_INTERN)) { */ /*if (msgctxt && !strcmp(msgctxt, BLF_I18NCONTEXT_DEFAULT_BPY_INTERN)) { */
if (msgctxt && !msgctxt[0]) { if (msgctxt && msgctxt[0] == BLF_I18NCONTEXT_DEFAULT_BPY[0]) {
/* BLF_I18NCONTEXT_DEFAULT_BPY_INTERN context is reserved and considered the same as default NULL one. */ /* BLF_I18NCONTEXT_DEFAULT_BPY context is reserved and considered the same as default NULL one. */
msgctxt = NULL; msgctxt = BLF_I18NCONTEXT_DEFAULT;
} }
ret = bl_locale_pgettext(msgctxt, msgid); ret = bl_locale_pgettext(msgctxt, msgid);
/* We assume if the returned string is the same (memory level) as the msgid, no translation was found, /* We assume if the returned string is the same (memory level) as the msgid, no translation was found,

@ -56,6 +56,7 @@ void defvert_remove_group(struct MDeformVert *dvert, struct
void defvert_clear(struct MDeformVert *dvert); void defvert_clear(struct MDeformVert *dvert);
int defvert_find_shared(const struct MDeformVert *dvert_a, const struct MDeformVert *dvert_b); int defvert_find_shared(const struct MDeformVert *dvert_a, const struct MDeformVert *dvert_b);
void BKE_defvert_array_free_elems(struct MDeformVert *dvert, int totvert);
void BKE_defvert_array_free(struct MDeformVert *dvert, int totvert); void BKE_defvert_array_free(struct MDeformVert *dvert, int totvert);
void BKE_defvert_array_copy(struct MDeformVert *dst, const struct MDeformVert *src, int totvert); void BKE_defvert_array_copy(struct MDeformVert *dst, const struct MDeformVert *src, int totvert);

@ -50,6 +50,7 @@ struct RenderData;
struct rctf; struct rctf;
struct MovieClip; struct MovieClip;
struct Main; struct Main;
struct RigidBodyWorld;
void BKE_object_workob_clear(struct Object *workob); void BKE_object_workob_clear(struct Object *workob);
void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob); void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struct Object *workob);
@ -100,7 +101,9 @@ int BKE_object_pose_context_check(struct Object *ob);
struct Object *BKE_object_pose_armature_get(struct Object *ob); struct Object *BKE_object_pose_armature_get(struct Object *ob);
void BKE_object_where_is_calc(struct Scene *scene, struct Object *ob); void BKE_object_where_is_calc(struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob);
void BKE_object_where_is_calc_time(struct Scene *scene, struct Object *ob, float ctime); void BKE_object_where_is_calc_time(struct Scene *scene, struct Object *ob, float ctime);
void BKE_object_where_is_calc_time_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob, float ctime);
void BKE_object_where_is_calc_simul(struct Scene *scene, struct Object *ob); void BKE_object_where_is_calc_simul(struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float obmat[4][4]); void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float obmat[4][4]);
@ -146,6 +149,7 @@ void BKE_object_tfm_protected_restore(struct Object *ob,
const short protectflag); const short protectflag);
void BKE_object_handle_update(struct Scene *scene, struct Object *ob); void BKE_object_handle_update(struct Scene *scene, struct Object *ob);
void BKE_object_handle_update_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob);
void BKE_object_sculpt_modifiers_changed(struct Object *ob); void BKE_object_sculpt_modifiers_changed(struct Object *ob);
int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot); int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);

@ -89,7 +89,7 @@ void BKE_rigidbody_remove_constraint(struct Scene *scene, struct Object *ob);
/* Simulation */ /* Simulation */
void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle); void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle);
void BKE_rigidbody_sync_transforms(struct Scene *scene, struct Object *ob, float ctime); void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime);
void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw); void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime); void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime);

@ -66,8 +66,8 @@ void txt_move_up (struct Text *text, short sel);
void txt_move_down (struct Text *text, short sel); void txt_move_down (struct Text *text, short sel);
void txt_move_left (struct Text *text, short sel); void txt_move_left (struct Text *text, short sel);
void txt_move_right (struct Text *text, short sel); void txt_move_right (struct Text *text, short sel);
void txt_jump_left (struct Text *text, short sel); void txt_jump_left (struct Text *text, bool sel, bool use_init_step);
void txt_jump_right (struct Text *text, short sel); void txt_jump_right (struct Text *text, bool sel, bool use_init_step);
void txt_move_bof (struct Text *text, short sel); void txt_move_bof (struct Text *text, short sel);
void txt_move_eof (struct Text *text, short sel); void txt_move_eof (struct Text *text, short sel);
void txt_move_bol (struct Text *text, short sel); void txt_move_bol (struct Text *text, short sel);

@ -967,7 +967,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
} }
else else
dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH);
if (flag & DUPLILIST_FOR_RENDER) { if (flag & DUPLILIST_FOR_RENDER) {
vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par); vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
@ -1094,7 +1094,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
} }
else { else {
dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); dm = mesh_get_derived_final(scene, par, CD_MASK_BAREMESH);
} }
totface = dm->getNumPolys(dm); totface = dm->getNumPolys(dm);

@ -588,11 +588,16 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
else if (texfall == 1) { else if (texfall == 1) {
BKE_brush_sample_tex_2D(scene, brush, xy, dstf, 0); BKE_brush_sample_tex_2D(scene, brush, xy, dstf, 0);
} }
else { else if (texfall == 2) {
BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0); BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
mul_v3_v3v3(dstf, rgba, brush_rgb); mul_v3_v3v3(dstf, rgba, brush_rgb);
dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius); dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
} }
else {
BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
copy_v3_v3(dstf, brush_rgb);
dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
}
} }
} }
} }

@ -1431,7 +1431,7 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
*/ */
if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) {
if (dm->numTessFaceData) { if (dm->numTessFaceData) {
setMaterial(userData, 1, NULL); setMaterial(userData, 1, &gattribs);
BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE); BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE);
} }

@ -809,7 +809,7 @@ void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int copyco
} }
void BKE_defvert_array_free(MDeformVert *dvert, int totvert) void BKE_defvert_array_free_elems(MDeformVert *dvert, int totvert)
{ {
/* Instead of freeing the verts directly, /* Instead of freeing the verts directly,
* call this function to delete any special * call this function to delete any special
@ -823,6 +823,18 @@ void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
for (i = 0; i < totvert; i++) { for (i = 0; i < totvert; i++) {
if (dvert[i].dw) MEM_freeN(dvert[i].dw); if (dvert[i].dw) MEM_freeN(dvert[i].dw);
} }
MEM_freeN(dvert);
} }
void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
{
/* Instead of freeing the verts directly,
* call this function to delete any special
* vert data */
if (!dvert)
return;
/* Free any special data from the verts */
BKE_defvert_array_free_elems(dvert, totvert);
MEM_freeN(dvert);
}

@ -2353,6 +2353,7 @@ static void dag_object_time_update_flags(Scene *scene, Object *ob)
if (object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA; if (object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
if ((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA; if ((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
// XXX: scene here may not be the scene that contains the rigidbody world affecting this!
if (ob->rigidbody_object && BKE_scene_check_rigidbody_active(scene)) if (ob->rigidbody_object && BKE_scene_check_rigidbody_active(scene))
ob->recalc |= OB_RECALC_OB; ob->recalc |= OB_RECALC_OB;
@ -2440,7 +2441,11 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s
if (do_time) { if (do_time) {
/* now if DagNode were part of base, the node->lay could be checked... */ /* now if DagNode were part of base, the node->lay could be checked... */
/* we do all now, since the scene_flush checks layers and clears recalc flags even */ /* we do all now, since the scene_flush checks layers and clears recalc flags even */
dag_object_time_update_flags(scene, ob);
/* NOTE: "sce_iter" not "scene" so that rigidbodies in background scenes work
* (i.e. muting + rbw availability can be checked and tagged properly) [#33970]
*/
dag_object_time_update_flags(sce_iter, ob);
} }
/* handled in next loop */ /* handled in next loop */

@ -2379,7 +2379,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
dot11 = d2[0] * d2[0] + d2[1] * d2[1]; dot11 = d2[0] * d2[0] + d2[1] * d2[1];
dot12 = d2[0] * d3[0] + d2[1] * d3[1]; dot12 = d2[0] * d3[0] + d2[1] * d3[1];
invDenom = 1 / (dot00 * dot11 - dot01 * dot01); invDenom = (dot00 * dot11 - dot01 * dot01);
invDenom = invDenom ? 1.0f / invDenom : 1.0f;
u = (dot11 * dot02 - dot01 * dot12) * invDenom; u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom;
@ -2399,7 +2400,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
dot11 = d2[0] * d2[0] + d2[1] * d2[1]; dot11 = d2[0] * d2[0] + d2[1] * d2[1];
dot12 = d2[0] * d3[0] + d2[1] * d3[1]; dot12 = d2[0] * d3[0] + d2[1] * d3[1];
invDenom = 1 / (dot00 * dot11 - dot01 * dot01); invDenom = (dot00 * dot11 - dot01 * dot01);
invDenom = invDenom ? 1.0f / invDenom : 1.0f;
u = (dot11 * dot02 - dot01 * dot12) * invDenom; u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom; v = (dot00 * dot12 - dot01 * dot02) * invDenom;

@ -562,7 +562,7 @@ int closest_point_on_surface(SurfaceModifierData *surmd, const float co[3], floa
if (mface->v4) if (mface->v4)
add_v3_v3(surface_vel, surmd->v[mface->v4].co); add_v3_v3(surface_vel, surmd->v[mface->v4].co);
mul_v3_fl(surface_vel, mface->v4 ? 0.25f : 0.333f); mul_v3_fl(surface_vel, mface->v4 ? 0.25f : (1.0f / 3.0f));
} }
return 1; return 1;
} }

@ -2737,6 +2737,14 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
if (rres.have_combined && layer == 0) { if (rres.have_combined && layer == 0) {
/* pass */ /* pass */
} }
else if (rect && layer == 0) {
/* rect32 is set when there's a Sequence pass, this pass seems
* to have layer=0 (this is from image_buttons.c)
* in this case we ignore float buffer, because it could have
* hung from previous pass which was float
*/
rectf = NULL;
}
else if (rres.layers.first) { else if (rres.layers.first) {
RenderLayer *rl = BLI_findlink(&rres.layers, layer - (rres.have_combined ? 1 : 0)); RenderLayer *rl = BLI_findlink(&rres.layers, layer - (rres.have_combined ? 1 : 0));
if (rl) { if (rl) {

@ -912,7 +912,7 @@ void outside_lattice(Lattice *lt)
bp->vec[1] += (1.0f - fac1) * bp1->vec[1] + fac1 * bp2->vec[1]; bp->vec[1] += (1.0f - fac1) * bp1->vec[1] + fac1 * bp2->vec[1];
bp->vec[2] += (1.0f - fac1) * bp1->vec[2] + fac1 * bp2->vec[2]; bp->vec[2] += (1.0f - fac1) * bp1->vec[2] + fac1 * bp2->vec[2];
mul_v3_fl(bp->vec, 0.3333333f); mul_v3_fl(bp->vec, 1.0f / 3.0f);
} }
} }

@ -1654,6 +1654,14 @@ static void polygonize(PROCESS *mbproc, MetaBall *mb)
} }
} }
/* could move to math api */
BLI_INLINE void copy_v3_fl3(float v[3], float x, float y, float z)
{
v[0] = x;
v[1] = y;
v[2] = z;
}
static float init_meta(Scene *scene, Object *ob) /* return totsize */ static float init_meta(Scene *scene, Object *ob) /* return totsize */
{ {
Scene *sce_iter = scene; Scene *sce_iter = scene;
@ -1730,6 +1738,7 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
float temp1[4][4], temp2[4][4], temp3[4][4]; float temp1[4][4], temp2[4][4], temp3[4][4];
float (*mat)[4] = NULL, (*imat)[4] = NULL; float (*mat)[4] = NULL, (*imat)[4] = NULL;
float max_x, max_y, max_z, min_x, min_y, min_z; float max_x, max_y, max_z, min_x, min_y, min_z;
float expx, expy, expz;
max_x = max_y = max_z = -3.4e38; max_x = max_y = max_z = -3.4e38;
min_x = min_y = min_z = 3.4e38; min_x = min_y = min_z = 3.4e38;
@ -1770,39 +1779,27 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
G_mb.mainb[a]->mat = (float *) mat; G_mb.mainb[a]->mat = (float *) mat;
G_mb.mainb[a]->imat = (float *) imat; G_mb.mainb[a]->imat = (float *) imat;
if (!MB_TYPE_SIZE_SQUARED(ml->type)) {
expx = ml->expx;
expy = ml->expy;
expz = ml->expz;
}
else {
expx = ml->expx * ml->expx;
expy = ml->expy * ml->expy;
expz = ml->expz * ml->expz;
}
/* untransformed Bounding Box of MetaElem */ /* untransformed Bounding Box of MetaElem */
/* 0 */ /* TODO, its possible the elem type has been changed and the exp* values can use a fallback */
G_mb.mainb[a]->bb->vec[0][0] = -ml->expx; copy_v3_fl3(G_mb.mainb[a]->bb->vec[0], -expx, -expy, -expz); /* 0 */
G_mb.mainb[a]->bb->vec[0][1] = -ml->expy; copy_v3_fl3(G_mb.mainb[a]->bb->vec[1], +expx, -expy, -expz); /* 1 */
G_mb.mainb[a]->bb->vec[0][2] = -ml->expz; copy_v3_fl3(G_mb.mainb[a]->bb->vec[2], +expx, +expy, -expz); /* 2 */
/* 1 */ copy_v3_fl3(G_mb.mainb[a]->bb->vec[3], -expx, +expy, -expz); /* 3 */
G_mb.mainb[a]->bb->vec[1][0] = ml->expx; copy_v3_fl3(G_mb.mainb[a]->bb->vec[4], -expx, -expy, +expz); /* 4 */
G_mb.mainb[a]->bb->vec[1][1] = -ml->expy; copy_v3_fl3(G_mb.mainb[a]->bb->vec[5], +expx, -expy, +expz); /* 5 */
G_mb.mainb[a]->bb->vec[1][2] = -ml->expz; copy_v3_fl3(G_mb.mainb[a]->bb->vec[6], +expx, +expy, +expz); /* 6 */
/* 2 */ copy_v3_fl3(G_mb.mainb[a]->bb->vec[7], -expx, +expy, +expz); /* 7 */
G_mb.mainb[a]->bb->vec[2][0] = ml->expx;
G_mb.mainb[a]->bb->vec[2][1] = ml->expy;
G_mb.mainb[a]->bb->vec[2][2] = -ml->expz;
/* 3 */
G_mb.mainb[a]->bb->vec[3][0] = -ml->expx;
G_mb.mainb[a]->bb->vec[3][1] = ml->expy;
G_mb.mainb[a]->bb->vec[3][2] = -ml->expz;
/* 4 */
G_mb.mainb[a]->bb->vec[4][0] = -ml->expx;
G_mb.mainb[a]->bb->vec[4][1] = -ml->expy;
G_mb.mainb[a]->bb->vec[4][2] = ml->expz;
/* 5 */
G_mb.mainb[a]->bb->vec[5][0] = ml->expx;
G_mb.mainb[a]->bb->vec[5][1] = -ml->expy;
G_mb.mainb[a]->bb->vec[5][2] = ml->expz;
/* 6 */
G_mb.mainb[a]->bb->vec[6][0] = ml->expx;
G_mb.mainb[a]->bb->vec[6][1] = ml->expy;
G_mb.mainb[a]->bb->vec[6][2] = ml->expz;
/* 7 */
G_mb.mainb[a]->bb->vec[7][0] = -ml->expx;
G_mb.mainb[a]->bb->vec[7][1] = ml->expy;
G_mb.mainb[a]->bb->vec[7][2] = ml->expz;
/* transformation of Metalem bb */ /* transformation of Metalem bb */
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)

@ -2999,6 +2999,36 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
} }
} }
/* note, results won't be correct if polygon is non-planar */
static float mesh_calc_poly_planar_area_centroid(MPoly *mpoly, MLoop *loopstart, MVert *mvarray, float cent[3])
{
int i;
float tri_area;
float total_area = 0.0f;
float v1[3], v2[3], v3[3], normal[3], tri_cent[3];
BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, normal);
copy_v3_v3(v1, mvarray[loopstart[0].v].co);
copy_v3_v3(v2, mvarray[loopstart[1].v].co);
zero_v3(cent);
for (i = 2; i < mpoly->totloop; i++) {
copy_v3_v3(v3, mvarray[loopstart[i].v].co);
tri_area = area_tri_signed_v3(v1, v2, v3, normal);
total_area += tri_area;
cent_tri_v3(tri_cent, v1, v2, v3);
madd_v3_v3fl(cent, tri_cent, tri_area);
copy_v3_v3(v2, v3);
}
mul_v3_fl(cent, 1.0f / total_area);
return total_area;
}
/** /**
* This function takes the difference between 2 vertex-coord-arrays * This function takes the difference between 2 vertex-coord-arrays
* (\a vert_cos_src, \a vert_cos_dst), * (\a vert_cos_src, \a vert_cos_dst),
@ -3292,8 +3322,7 @@ int BKE_mesh_center_centroid(Mesh *me, float cent[3])
/* calculate a weighted average of polygon centroids */ /* calculate a weighted average of polygon centroids */
for (mpoly = me->mpoly; i--; mpoly++) { for (mpoly = me->mpoly; i--; mpoly++) {
BKE_mesh_calc_poly_center(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent); poly_area = mesh_calc_poly_planar_area_centroid(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
poly_area = BKE_mesh_calc_poly_area(mpoly, me->mloop + mpoly->loopstart, me->mvert, NULL);
madd_v3_v3fl(cent, poly_cent, poly_area); madd_v3_v3fl(cent, poly_cent, poly_area);
total_area += poly_area; total_area += poly_area;

@ -58,6 +58,7 @@
#include "DNA_world_types.h" #include "DNA_world_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DNA_property_types.h" #include "DNA_property_types.h"
#include "DNA_rigidbody_types.h"
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
#include "BLI_math.h" #include "BLI_math.h"
@ -2027,7 +2028,7 @@ static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
else { else {
add_v3_v3v3(mat[3], v1, v2); add_v3_v3v3(mat[3], v1, v2);
add_v3_v3(mat[3], v3); add_v3_v3(mat[3], v3);
mul_v3_fl(mat[3], 0.3333333f); mul_v3_fl(mat[3], 1.0f / 3.0f);
} }
} }
} }
@ -2130,7 +2131,8 @@ static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[
return 1; return 1;
} }
void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime) /* note, scene is the active scene while actual_scene is the scene the object resides in */
void BKE_object_where_is_calc_time_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob, float ctime)
{ {
if (ob == NULL) return; if (ob == NULL) return;
@ -2156,7 +2158,8 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
BKE_object_to_mat4(ob, ob->obmat); BKE_object_to_mat4(ob, ob->obmat);
} }
BKE_rigidbody_sync_transforms(scene, ob, ctime); /* read values pushed into RBO from sim/cache... */
BKE_rigidbody_sync_transforms(rbw, ob, ctime);
/* solve constraints */ /* solve constraints */
if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) { if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
@ -2172,6 +2175,11 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
else ob->transflag &= ~OB_NEG_SCALE; else ob->transflag &= ~OB_NEG_SCALE;
} }
void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
{
BKE_object_where_is_calc_time_ex(scene, NULL, ob, ctime);
}
/* get object transformation matrix without recalculating dependencies and /* get object transformation matrix without recalculating dependencies and
* constraints -- assume dependencies are already solved by depsgraph. * constraints -- assume dependencies are already solved by depsgraph.
* no changes to object and it's parent would be done. * no changes to object and it's parent would be done.
@ -2193,9 +2201,13 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
} }
} }
void BKE_object_where_is_calc(struct Scene *scene, Object *ob) void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
{ {
BKE_object_where_is_calc_time(scene, ob, BKE_scene_frame_get(scene)); BKE_object_where_is_calc_time_ex(scene, rbw, ob, BKE_scene_frame_get(scene));
}
void BKE_object_where_is_calc(Scene *scene, Object *ob)
{
BKE_object_where_is_calc_time_ex(scene, NULL, ob, BKE_scene_frame_get(scene));
} }
void BKE_object_where_is_calc_simul(Scene *scene, Object *ob) void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
@ -2631,7 +2643,8 @@ int BKE_object_parent_loop_check(const Object *par, const Object *ob)
/* the main object update call, for object matrix, constraints, keys and displist (modifiers) */ /* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
/* requires flags to be set! */ /* requires flags to be set! */
void BKE_object_handle_update(Scene *scene, Object *ob) /* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
void BKE_object_handle_update_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
{ {
if (ob->recalc & OB_RECALC_ALL) { if (ob->recalc & OB_RECALC_ALL) {
/* speed optimization for animation lookups */ /* speed optimization for animation lookups */
@ -2672,7 +2685,7 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
copy_m4_m4(ob->obmat, ob->proxy_from->obmat); copy_m4_m4(ob->obmat, ob->proxy_from->obmat);
} }
else else
BKE_object_where_is_calc(scene, ob); BKE_object_where_is_calc_ex(scene, rbw, ob);
} }
if (ob->recalc & OB_RECALC_DATA) { if (ob->recalc & OB_RECALC_DATA) {
@ -2826,6 +2839,15 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
// printf("set proxy pointer for later group stuff %s\n", ob->id.name); // printf("set proxy pointer for later group stuff %s\n", ob->id.name);
} }
} }
/* WARNING: "scene" here may not be the scene object actually resides in.
* When dealing with background-sets, "scene" is actually the active scene.
* e.g. "scene" <-- set 1 <-- set 2 ("ob" lives here) <-- set 3 <-- ... <-- set n
* rigid bodies depend on their world so use BKE_object_handle_update_ex() to also pass along the corrent rigid body world
*/
void BKE_object_handle_update(Scene *scene, Object *ob)
{
BKE_object_handle_update_ex(scene, NULL, ob);
}
void BKE_object_sculpt_modifiers_changed(Object *ob) void BKE_object_sculpt_modifiers_changed(Object *ob)
{ {

@ -802,7 +802,7 @@ static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, Ch
if (mface->v4) if (mface->v4)
psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv); psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
else else
psys_uv_to_w(0.33333f, 0.33333f, mface->v4, pa->fuv); psys_uv_to_w(1.0f / 3.0f, 1.0f / 3.0f, mface->v4, pa->fuv);
} }
else { else {
ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel); ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);

@ -1130,11 +1130,9 @@ static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
} }
} }
} }
/* Sync rigid body and object transformations */ /* Sync rigid body and object transformations */
void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime) void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
{ {
RigidBodyWorld *rbw = scene->rigidbody_world;
RigidBodyOb *rbo = ob->rigidbody_object; RigidBodyOb *rbo = ob->rigidbody_object;
/* keep original transform for kinematic and passive objects */ /* keep original transform for kinematic and passive objects */
@ -1165,6 +1163,7 @@ void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime)
} }
} }
/* Used when cancelling transforms - return rigidbody and object to initial states */
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
{ {
RigidBodyOb *rbo = ob->rigidbody_object; RigidBodyOb *rbo = ob->rigidbody_object;
@ -1216,6 +1215,8 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL); BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
cache = rbw->pointcache; cache = rbw->pointcache;
rbw->flag &= ~RBW_FLAG_FRAME_UPDATE;
/* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */ /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
if (rbw->physics_world == NULL || rbw->numbodies != BLI_countlist(&rbw->group->gobject)) { if (rbw->physics_world == NULL || rbw->numbodies != BLI_countlist(&rbw->group->gobject)) {
cache->flag |= PTCACHE_OUTDATED; cache->flag |= PTCACHE_OUTDATED;

@ -1115,11 +1115,19 @@ static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent)
} }
static void scene_flag_rbw_recursive(Scene *scene)
{
if (scene->set)
scene_flag_rbw_recursive(scene->set);
if (BKE_scene_check_rigidbody_active(scene))
scene->rigidbody_world->flag |= RBW_FLAG_FRAME_UPDATE;
}
static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent) static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
{ {
Base *base; Base *base;
scene->customdata_mask = scene_parent->customdata_mask; scene->customdata_mask = scene_parent->customdata_mask;
/* sets first, we allow per definition current scene to have /* sets first, we allow per definition current scene to have
@ -1127,11 +1135,27 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
if (scene->set) if (scene->set)
scene_update_tagged_recursive(bmain, scene->set, scene_parent); scene_update_tagged_recursive(bmain, scene->set, scene_parent);
/* run rigidbody sim
* - calculate/read values from cache into RBO's, to get flushed
* later when objects are evaluated (if they're tagged for eval)
*/
// XXX: this position may still change, objects not being updated correctly before simulation is run
// NOTE: current position is so that rigidbody sim affects other objects
if (BKE_scene_check_rigidbody_active(scene) && scene->rigidbody_world->flag & RBW_FLAG_FRAME_UPDATE) {
/* we use frame time of parent (this is "scene" itself for top-level of sets recursion),
* as that is the active scene controlling all timing in file at the moment
*/
float ctime = BKE_scene_frame_get(scene_parent);
/* however, "scene" contains the rigidbody world needed for eval... */
BKE_rigidbody_do_simulation(scene, ctime);
}
/* scene objects */ /* scene objects */
for (base = scene->base.first; base; base = base->next) { for (base = scene->base.first; base; base = base->next) {
Object *ob = base->object; Object *ob = base->object;
BKE_object_handle_update(scene_parent, ob); BKE_object_handle_update_ex(scene_parent, scene->rigidbody_world, ob);
if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP))
group_handle_recalc_and_update(scene_parent, ob, ob->dup_group); group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
@ -1232,13 +1256,7 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
* such as Scene->World->MTex/Texture) can still get correctly overridden. * such as Scene->World->MTex/Texture) can still get correctly overridden.
*/ */
BKE_animsys_evaluate_all_animation(bmain, sce, ctime); BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
/*...done with recusrive funcs */ /*...done with recursive funcs */
/* run rigidbody sim */
// XXX: this position may still change, objects not being updated correctly before simulation is run
// NOTE: current position is so that rigidbody sim affects other objects
if (BKE_scene_check_rigidbody_active(sce))
BKE_rigidbody_do_simulation(sce, ctime);
/* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later
* when trying to find materials with drivers that need evaluating [#32017] * when trying to find materials with drivers that need evaluating [#32017]
@ -1246,6 +1264,9 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
tag_main_idcode(bmain, ID_MA, FALSE); tag_main_idcode(bmain, ID_MA, FALSE);
tag_main_idcode(bmain, ID_LA, FALSE); tag_main_idcode(bmain, ID_LA, FALSE);
/* flag rigid body worlds for update */
scene_flag_rbw_recursive(sce);
/* BKE_object_handle_update() on all objects, groups and sets */ /* BKE_object_handle_update() on all objects, groups and sets */
scene_update_tagged_recursive(bmain, sce, sce); scene_update_tagged_recursive(bmain, sce, sce);

@ -1820,8 +1820,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
StripCrop c = {0}; StripCrop c = {0};
StripTransform t = {0}; StripTransform t = {0};
int sx, sy, dx, dy; int sx, sy, dx, dy;
double xscale = 1.0;
double yscale = 1.0;
if (is_proxy_image) { if (is_proxy_image) {
double f = seq_rendersize_to_scale_factor(context.preview_render_size); double f = seq_rendersize_to_scale_factor(context.preview_render_size);
@ -1838,21 +1836,23 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
t = *seq->strip->transform; t = *seq->strip->transform;
} }
xscale = context.scene->r.xsch ? ((double)context.rectx / (double)context.scene->r.xsch) : 1.0; if (is_preprocessed) {
yscale = context.scene->r.ysch ? ((double)context.recty / (double)context.scene->r.ysch) : 1.0; double xscale = context.scene->r.xsch ? ((double)context.rectx / (double)context.scene->r.xsch) : 1.0;
double yscale = context.scene->r.ysch ? ((double)context.recty / (double)context.scene->r.ysch) : 1.0;
xscale /= (double)context.rectx / (double)ibuf->x; if (seq->flag & SEQ_USE_TRANSFORM) {
yscale /= (double)context.recty / (double)ibuf->y; t.xofs *= xscale;
t.yofs *= yscale;
c.left *= xscale; c.right *= xscale; }
c.top *= yscale; c.bottom *= yscale; if (seq->flag & SEQ_USE_CROP) {
c.left *= xscale;
t.xofs *= xscale; t.yofs *= yscale; c.right *= xscale;
c.top *= yscale;
c.bottom *= yscale;
}
}
sx = ibuf->x - c.left - c.right; sx = ibuf->x - c.left - c.right;
sy = ibuf->y - c.top - c.bottom; sy = ibuf->y - c.top - c.bottom;
dx = sx;
dy = sy;
if (seq->flag & SEQ_USE_TRANSFORM) { if (seq->flag & SEQ_USE_TRANSFORM) {
if (is_preprocessed) { if (is_preprocessed) {
@ -1864,6 +1864,10 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
dy = context.scene->r.ysch; dy = context.scene->r.ysch;
} }
} }
else {
dx = sx;
dy = sy;
}
if (c.top + c.bottom >= ibuf->y || if (c.top + c.bottom >= ibuf->y ||
c.left + c.right >= ibuf->x || c.left + c.right >= ibuf->x ||

@ -1583,7 +1583,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
} }
/* set fire reaction coordinate */ /* set fire reaction coordinate */
if (fuel && fuel[index]) { if (fuel && fuel[index] > FLT_EPSILON) {
/* instead of using 1.0 for all new fuel add slight falloff /* instead of using 1.0 for all new fuel add slight falloff
* to reduce flow blockiness */ * to reduce flow blockiness */
float value = 1.0f - powf(1.0f - emission_value, 2.0f); float value = 1.0f - powf(1.0f - emission_value, 2.0f);
@ -1591,6 +1591,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
if (value > react[index]) { if (value > react[index]) {
float f = fuel_flow / fuel[index]; float f = fuel_flow / fuel[index];
react[index] = value * f + (1.0f - f) * react[index]; react[index] = value * f + (1.0f - f) * react[index];
CLAMP(react[index], 0.0f, value);
} }
} }
} }

@ -38,12 +38,12 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_path_util.h" #include "BLI_path_util.h"
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_string_cursor_utf8.h" #include "BLI_string_cursor_utf8.h"
#include "BLI_string_utf8.h" #include "BLI_string_utf8.h"
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "BLI_fileops.h" #include "BLI_fileops.h"
#include "DNA_constraint_types.h" #include "DNA_constraint_types.h"
@ -936,7 +936,7 @@ void txt_move_right(Text *text, short sel)
if (!sel) txt_pop_sel(text); if (!sel) txt_pop_sel(text);
} }
void txt_jump_left(Text *text, short sel) void txt_jump_left(Text *text, bool sel, bool use_init_step)
{ {
TextLine **linep; TextLine **linep;
int *charp; int *charp;
@ -948,12 +948,12 @@ void txt_jump_left(Text *text, short sel)
BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len, BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
charp, STRCUR_DIR_PREV, charp, STRCUR_DIR_PREV,
STRCUR_JUMP_DELIM); STRCUR_JUMP_DELIM, use_init_step);
if (!sel) txt_pop_sel(text); if (!sel) txt_pop_sel(text);
} }
void txt_jump_right(Text *text, short sel) void txt_jump_right(Text *text, bool sel, bool use_init_step)
{ {
TextLine **linep; TextLine **linep;
int *charp; int *charp;
@ -965,7 +965,7 @@ void txt_jump_right(Text *text, short sel)
BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len, BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
charp, STRCUR_DIR_NEXT, charp, STRCUR_DIR_NEXT,
STRCUR_JUMP_DELIM); STRCUR_JUMP_DELIM, use_init_step);
if (!sel) txt_pop_sel(text); if (!sel) txt_pop_sel(text);
} }
@ -2402,7 +2402,7 @@ void txt_delete_char(Text *text)
void txt_delete_word(Text *text) void txt_delete_word(Text *text)
{ {
txt_jump_right(text, 1); txt_jump_right(text, true, true);
txt_delete_sel(text); txt_delete_sel(text);
} }
@ -2451,7 +2451,7 @@ void txt_backspace_char(Text *text)
void txt_backspace_word(Text *text) void txt_backspace_word(Text *text)
{ {
txt_jump_left(text, 1); txt_jump_left(text, true, true);
txt_delete_sel(text); txt_delete_sel(text);
} }

@ -142,7 +142,7 @@ static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 0,
/* Areas */ /* Areas */
static struct bUnitDef buMetricAreaDef[] = { static struct bUnitDef buMetricAreaDef[] = {
{"square kilometer", "square kilometers", "km²", "km2", "Square Kilometers", UN_SC_KM * UN_SC_KM, 0.0, B_UNIT_DEF_NONE}, {"square kilometer", "square kilometers", "km²", "km2", "Square Kilometers", UN_SC_KM * UN_SC_KM, 0.0, B_UNIT_DEF_NONE},
{"square hectometer", "square hectometers", "hm²", "hm2", "Square Hectometers", UN_SC_HM * UN_SC_HM, 0.0, B_UNIT_DEF_NONE}, /* hectare */ {"square hectometer", "square hectometers", "hm²", "hm2", "Square Hectometers", UN_SC_HM * UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS}, /* hectare */
{"square dekameter", "square dekameters", "dam²", "dam2", "Square Dekameters", UN_SC_DAM * UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS}, /* are */ {"square dekameter", "square dekameters", "dam²", "dam2", "Square Dekameters", UN_SC_DAM * UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS}, /* are */
{"square meter", "square meters", "", "m2", "Square Meters", UN_SC_M * UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {"square meter", "square meters", "", "m2", "Square Meters", UN_SC_M * UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"square decimeter", "square decimetees", "dm²", "dm2", "Square Decimeters", UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS}, {"square decimeter", "square decimetees", "dm²", "dm2", "Square Decimeters", UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
@ -168,7 +168,7 @@ static struct bUnitCollection buImperialAreaCollecton = {buImperialAreaDef, 4, 0
/* Volumes */ /* Volumes */
static struct bUnitDef buMetricVolDef[] = { static struct bUnitDef buMetricVolDef[] = {
{"cubic kilometer", "cubic kilometers", "km³", "km3", "Cubic Kilometers", UN_SC_KM * UN_SC_KM * UN_SC_KM, 0.0, B_UNIT_DEF_NONE}, {"cubic kilometer", "cubic kilometers", "km³", "km3", "Cubic Kilometers", UN_SC_KM * UN_SC_KM * UN_SC_KM, 0.0, B_UNIT_DEF_NONE},
{"cubic hectometer", "cubic hectometers", "hm³", "hm3", "Cubic Hectometers", UN_SC_HM * UN_SC_HM * UN_SC_HM, 0.0, B_UNIT_DEF_NONE}, {"cubic hectometer", "cubic hectometers", "hm³", "hm3", "Cubic Hectometers", UN_SC_HM * UN_SC_HM * UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS},
{"cubic dekameter", "cubic dekameters", "dam³", "dam3", "Cubic Dekameters", UN_SC_DAM * UN_SC_DAM * UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS}, {"cubic dekameter", "cubic dekameters", "dam³", "dam3", "Cubic Dekameters", UN_SC_DAM * UN_SC_DAM * UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS},
{"cubic meter", "cubic meters", "", "m3", "Cubic Meters", UN_SC_M * UN_SC_M * UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {"cubic meter", "cubic meters", "", "m3", "Cubic Meters", UN_SC_M * UN_SC_M * UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"cubic decimeter", "cubic decimeters", "dm³", "dm3", "Cubic Decimeters", UN_SC_DM * UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS}, {"cubic decimeter", "cubic decimeters", "dm³", "dm3", "Cubic Decimeters", UN_SC_DM * UN_SC_DM * UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
@ -194,9 +194,9 @@ static struct bUnitCollection buImperialVolCollecton = {buImperialVolDef, 4, 0,
/* Mass */ /* Mass */
static struct bUnitDef buMetricMassDef[] = { static struct bUnitDef buMetricMassDef[] = {
{"ton", "tonnes", "ton", "t", "1000 Kilograms", UN_SC_MTON, 0.0, B_UNIT_DEF_NONE}, {"ton", "tonnes", "ton", "t", "1000 Kilograms", UN_SC_MTON, 0.0, B_UNIT_DEF_NONE},
{"quintal", "quintals", "ql", "q", "100 Kilograms", UN_SC_QL, 0.0, B_UNIT_DEF_NONE}, {"quintal", "quintals", "ql", "q", "100 Kilograms", UN_SC_QL, 0.0, B_UNIT_DEF_SUPPRESS},
{"kilogram", "kilograms", "kg", NULL, "Kilograms", UN_SC_KG, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {"kilogram", "kilograms", "kg", NULL, "Kilograms", UN_SC_KG, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"hectogram", "hectograms", "hg", NULL, "Hectograms", UN_SC_HG, 0.0, B_UNIT_DEF_NONE}, {"hectogram", "hectograms", "hg", NULL, "Hectograms", UN_SC_HG, 0.0, B_UNIT_DEF_SUPPRESS},
{"dekagram", "dekagrams", "dag", NULL, "10 Grams", UN_SC_DAG, 0.0, B_UNIT_DEF_SUPPRESS}, {"dekagram", "dekagrams", "dag", NULL, "10 Grams", UN_SC_DAG, 0.0, B_UNIT_DEF_SUPPRESS},
{"gram", "grams", "g", NULL, "Grams", UN_SC_G, 0.0, B_UNIT_DEF_NONE}, {"gram", "grams", "g", NULL, "Grams", UN_SC_G, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}

@ -51,6 +51,7 @@ float normal_quad_v3(float r[3], const float a[3], const float b[3], const float
float area_tri_v2(const float a[2], const float b[2], const float c[2]); float area_tri_v2(const float a[2], const float b[2], const float c[2]);
float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]); float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]);
float area_tri_v3(const float a[3], const float b[3], const float c[3]); float area_tri_v3(const float a[3], const float b[3], const float c[3]);
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3]);
float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]); float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
float area_poly_v3(int nr, float verts[][3], const float normal[3]); float area_poly_v3(int nr, float verts[][3], const float normal[3]);
float area_poly_v2(int nr, float verts[][2]); float area_poly_v2(int nr, float verts[][2]);

@ -88,6 +88,7 @@ void mul_serie_m4(float R[4][4],
void mul_m4_v3(float M[4][4], float r[3]); void mul_m4_v3(float M[4][4], float r[3]);
void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]); void mul_v3_m4v3(float r[3], float M[4][4], const float v[3]);
void mul_v2_m2v2(float r[2], float M[2][2], const float v[2]);
void mul_mat3_m4_v3(float M[4][4], float r[3]); void mul_mat3_m4_v3(float M[4][4], float r[3]);
void mul_m4_v4(float M[4][4], float r[4]); void mul_m4_v4(float M[4][4], float r[4]);
void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]); void mul_v4_m4v4(float r[4], float M[4][4], const float v[4]);
@ -170,6 +171,7 @@ void mat4_to_size(float r[3], float M[4][4]);
void translate_m4(float mat[4][4], float tx, float ty, float tz); void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m4(float mat[4][4], const char axis, const float angle); void rotate_m4(float mat[4][4], const char axis, const float angle);
void rotate_m2(float mat[2][2], const float angle);
void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]); void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);

@ -46,6 +46,6 @@ int BLI_str_cursor_step_prev_utf8(const char *str, size_t maxlen, int *pos);
void BLI_str_cursor_step_utf8(const char *str, size_t maxlen, void BLI_str_cursor_step_utf8(const char *str, size_t maxlen,
int *pos, strCursorJumpDirection direction, int *pos, strCursorJumpDirection direction,
strCursorJumpType jump); strCursorJumpType jump, bool use_init_step);
#endif /* __BLI_STRING_CURSOR_UTF8_H__ */ #endif /* __BLI_STRING_CURSOR_UTF8_H__ */

@ -245,6 +245,10 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
BLI_freenode *newhead = addr; BLI_freenode *newhead = addr;
if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) { if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
#ifndef NDEBUG
/* this will detect double free's */
BLI_assert(newhead->freeword != FREEWORD);
#endif
newhead->freeword = FREEWORD; newhead->freeword = FREEWORD;
} }

@ -111,7 +111,7 @@ int BLI_file_gzip(const char *from, const char *to)
return rval; return rval;
} }
/* gzip the file in from_file and write it to memery to_mem, at most size bytes. /* gzip the file in from_file and write it to memory to_mem, at most size bytes.
* return the unziped size * return the unziped size
*/ */
char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r) char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r)
@ -283,7 +283,7 @@ int BLI_move(const char *file, const char *to)
{ {
int err; int err;
/* windows doesn't support moveing to a directory /* windows doesn't support moving to a directory
* it has to be 'mv filename filename' and not * it has to be 'mv filename filename' and not
* 'mv filename destdir' */ * 'mv filename destdir' */

@ -39,9 +39,9 @@
void cent_tri_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3]) void cent_tri_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3])
{ {
cent[0] = 0.33333f * (v1[0] + v2[0] + v3[0]); cent[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
cent[1] = 0.33333f * (v1[1] + v2[1] + v3[1]); cent[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
cent[2] = 0.33333f * (v1[2] + v2[2] + v3[2]); cent[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
} }
void cent_quad_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3]) void cent_quad_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
@ -129,6 +129,22 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
return (len / 2.0f); return (len / 2.0f);
} }
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3])
{
float area, vec1[3], vec2[3], n[3];
sub_v3_v3v3(vec1, v3, v2);
sub_v3_v3v3(vec2, v1, v2);
cross_v3_v3v3(n, vec1, vec2);
area = len_v3(n) / 2.0f;
/* negate area for flipped triangles */
if (dot_v3v3(n, normal) < 0.0f)
area = -area;
return area;
}
float area_poly_v3(int nr, float verts[][3], const float normal[3]) float area_poly_v3(int nr, float verts[][3], const float normal[3])
{ {
int a, px, py; int a, px, py;
@ -3578,25 +3594,42 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl
/* evaluate if entire quad is a proper convex quad */ /* evaluate if entire quad is a proper convex quad */
int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]) int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{ {
float nor[3], nor1[3], nor2[3], vec[4][2]; float nor[3], nor_a[3], nor_b[3], vec[4][2];
float mat[3][3]; float mat[3][3];
const bool is_ok_a = (normal_tri_v3(nor_a, v1, v2, v3) > FLT_EPSILON);
const bool is_ok_b = (normal_tri_v3(nor_b, v1, v3, v4) > FLT_EPSILON);
/* define projection, do both trias apart, quad is undefined! */ /* define projection, do both trias apart, quad is undefined! */
normal_tri_v3(nor1, v1, v2, v3); /* check normal length incase one size is zero area */
normal_tri_v3(nor2, v1, v3, v4); if (is_ok_a) {
if (is_ok_b) {
/* use both, most common outcome */
/* when the face is folded over as 2 tris we probably don't want to create /* when the face is folded over as 2 tris we probably don't want to create
* a quad from it, but go ahead with the intersection test since this * a quad from it, but go ahead with the intersection test since this
* isn't a function for degenerate faces */ * isn't a function for degenerate faces */
if (UNLIKELY(dot_v3v3(nor1, nor2) < 0.0f)) { if (UNLIKELY(dot_v3v3(nor_a, nor_b) < 0.0f)) {
/* flip so adding normals in the opposite direction /* flip so adding normals in the opposite direction
* doesnt give a zero length vector */ * doesn't give a zero length vector */
negate_v3(nor2); negate_v3(nor_b);
} }
add_v3_v3v3(nor, nor1, nor2); add_v3_v3v3(nor, nor_a, nor_b);
normalize_v3(nor); normalize_v3(nor);
}
else {
copy_v3_v3(nor, nor_a); /* only 'a' */
}
}
else {
if (is_ok_b) {
copy_v3_v3(nor, nor_b); /* only 'b' */
}
else {
return false; /* both zero, we can't do anything useful here */
}
}
axis_dominant_v3_to_m3(mat, nor); axis_dominant_v3_to_m3(mat, nor);
@ -3606,12 +3639,12 @@ int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], c
mul_v2_m3v3(vec[3], mat, v4); mul_v2_m3v3(vec[3], mat, v4);
/* linetests, the 2 diagonals have to instersect to be convex */ /* linetests, the 2 diagonals have to instersect to be convex */
return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0) ? TRUE : FALSE; return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0);
} }
int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{ {
/* linetests, the 2 diagonals have to instersect to be convex */ /* linetests, the 2 diagonals have to instersect to be convex */
return (isect_line_line_v2(v1, v3, v2, v4) > 0) ? TRUE : FALSE; return (isect_line_line_v2(v1, v3, v2, v4) > 0);
} }

@ -344,6 +344,15 @@ void mul_v3_m4v3(float in[3], float mat[4][4], const float vec[3])
in[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2]; in[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
} }
void mul_v2_m2v2(float r[2], float mat[2][2], const float vec[2])
{
float x;
x = vec[0];
r[0] = mat[0][0] * x + mat[1][0] * vec[1];
r[1] = mat[0][1] * x + mat[1][1] * vec[1];
}
/* same as mul_m4_v3() but doesnt apply translation component */ /* same as mul_m4_v3() but doesnt apply translation component */
void mul_mat3_m4_v3(float mat[4][4], float vec[3]) void mul_mat3_m4_v3(float mat[4][4], float vec[3])
{ {
@ -1304,6 +1313,13 @@ void rotate_m4(float mat[4][4], const char axis, const float angle)
} }
} }
void rotate_m2(float mat[2][2], const float angle)
{
mat[0][0] = mat[1][1] = cosf(angle);
mat[0][1] = sinf(angle);
mat[1][0] = -mat[0][1];
}
void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight) void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
{ {
float srot[3][3], drot[3][3]; float srot[3][3], drot[3][3];

Some files were not shown because too many files have changed in this diff Show More